Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2008-02-21 23:25:18 +0000
committereutarass2008-02-21 23:25:18 +0000
commit521178c66ba2989ab837a9d7bb1c4a75216cfde2 (patch)
tree712d92bd8ef1fd4860d8f56f8a9b905bb2f216c8 /plugins/org.eclipse.tm.tcf.dsf
parent39964814a5c76b9c259bb2f670cb84e4d299abef (diff)
downloadorg.eclipse.tcf-521178c66ba2989ab837a9d7bb1c4a75216cfde2.tar.gz
org.eclipse.tcf-521178c66ba2989ab837a9d7bb1c4a75216cfde2.tar.xz
org.eclipse.tcf-521178c66ba2989ab837a9d7bb1c4a75216cfde2.zip
In order to comply with naming conventions at Eclipse, plugins, packages, etc. are renamed from com.windriver.* to org.eclipse.tm.*
Copyright notices are updated to include year 2008.
Diffstat (limited to 'plugins/org.eclipse.tm.tcf.dsf')
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/.classpath7
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/.project28
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.core.prefs272
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.ui.prefs4
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/META-INF/MANIFEST.MF20
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/about.html28
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/build.properties8
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/plugin.properties13
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/plugin.xml15
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/Activator.java65
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFExecuter.java201
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java62
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchDelegate.java24
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java83
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java17
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java85
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java306
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java62
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java307
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java614
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java23
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java1060
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java1023
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java516
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java233
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java23
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java106
27 files changed, 5205 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tm.tcf.dsf/.classpath b/plugins/org.eclipse.tm.tcf.dsf/.classpath
new file mode 100644
index 000000000..304e86186
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.tm.tcf.dsf/.project b/plugins/org.eclipse.tm.tcf.dsf/.project
new file mode 100644
index 000000000..68c416def
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.tcf.dsf</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0bf81e2f5
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,272 @@
+#Tue Feb 05 15:38:16 CET 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..abbc7248f
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Wed Jan 09 12:21:30 PST 2008
+eclipse.preferences.version=1
+formatter_profile=_Java STD
+formatter_settings_version=11
diff --git a/plugins/org.eclipse.tm.tcf.dsf/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf.dsf/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..39e57e150
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.tcf.dsf;singleton:=true
+Bundle-Version: 0.2.0
+Bundle-Activator: org.eclipse.tm.internal.tcf.dsf.Activator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.debug.core,
+ org.eclipse.core.resources,
+ org.eclipse.dd.dsf,
+ org.eclipse.dd.dsf.debug,
+ org.eclipse.cdt.core,
+ org.eclipse.tm.tcf,
+ org.eclipse.tm.tcf.debug
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.tm.internal.tcf.dsf.launch,
+ org.eclipse.tm.internal.tcf.dsf.services
diff --git a/plugins/org.eclipse.tm.tcf.dsf/about.html b/plugins/org.eclipse.tm.tcf.dsf/about.html
new file mode 100644
index 000000000..6c5b3615b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>January 10, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/org.eclipse.tm.tcf.dsf/build.properties b/plugins/org.eclipse.tm.tcf.dsf/build.properties
new file mode 100644
index 000000000..2b6399957
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ plugin.properties
+src.includes = about.html
diff --git a/plugins/org.eclipse.tm.tcf.dsf/plugin.properties b/plugins/org.eclipse.tm.tcf.dsf/plugin.properties
new file mode 100644
index 000000000..ee6aa5831
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Wind River Systems - initial implementation
+###############################################################################
+pluginName = TCF/DSF Integration Core
+providerName = Eclipse.org
+
diff --git a/plugins/org.eclipse.tm.tcf.dsf/plugin.xml b/plugins/org.eclipse.tm.tcf.dsf/plugin.xml
new file mode 100644
index 000000000..03786907c
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.debug.core.launchConfigurationTypes">
+ <launchConfigurationType
+ sourceLocatorId="org.eclipse.tm.tcf.debug.SourceLocator"
+ name="DSF over TCF"
+ sourcePathComputerId="org.eclipse.tm.tcf.debug.SourcePathComputer"
+ delegate="org.eclipse.tm.internal.tcf.dsf.launch.TCFDSFLaunchDelegate"
+ modes="debug"
+ id="org.eclipse.tm.tcf.dsf.LaunchConfigurationType">
+ </launchConfigurationType>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/Activator.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/Activator.java
new file mode 100644
index 000000000..9d71d4f25
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/Activator.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.tm.tcf.dsf.core";
+
+ // The shared instance
+ private static Activator plugin;
+ private static BundleContext bundle_context;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ bundle_context = context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ public static BundleContext getBundleContext() {
+ return bundle_context;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFExecuter.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFExecuter.java
new file mode 100644
index 000000000..309159c89
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFExecuter.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.launch;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+
+public class TCFDSFExecuter extends AbstractExecutorService implements DsfExecutor {
+
+ private class ScheduledFutureTask<V> extends FutureTask<V> implements ScheduledFuture<V> {
+
+ private long time; // Milliseconds
+ private final int id;
+ private final long period; // Milliseconds
+
+ public ScheduledFutureTask(long delay, long period, Runnable runnable, V result) {
+ super(runnable, result);
+ time = System.currentTimeMillis() + delay;
+ id = sf_count++;
+ this.period = period;
+ }
+
+ public ScheduledFutureTask(long delay, Callable<V> callable) {
+ super(callable);
+ time = System.currentTimeMillis() + delay;
+ id = sf_count++;
+ period = 0;
+ }
+
+ public long getDelay(TimeUnit unit) {
+ return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ public int compareTo(Delayed o) {
+ if (o == this) return 0;
+ ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)o;
+ if (time < x.time) return -1;
+ if (time > x.time) return +1;
+ if (id < x.id) return -1;
+ if (id > x.id) return +1;
+ assert false;
+ return 0;
+ }
+
+ public void run() {
+ if (period == 0) {
+ super.run();
+ }
+ else {
+ boolean ok = super.runAndReset();
+ synchronized (TCFDSFExecuter.this) {
+ // Reschedule if not canceled and not shutdown
+ if (ok && !is_shutdown) {
+ time = period > 0 ? time + period : System.currentTimeMillis() - period;
+ queue.add(this);
+ notify();
+ }
+ }
+ }
+ }
+ }
+
+ private static int sf_count = 0;
+ private final TreeSet<ScheduledFutureTask<?>> queue = new TreeSet<ScheduledFutureTask<?>>();
+ private final Thread thread;
+ private boolean is_shutdown;
+ private boolean is_terminated;
+
+ public TCFDSFExecuter() {
+ thread = new Thread(new Runnable() {
+ public void run() {
+ synchronized (TCFDSFExecuter.this) {
+ try {
+ while (true) {
+ if (queue.isEmpty()) {
+ if (is_shutdown) break;
+ TCFDSFExecuter.this.wait();
+ }
+ else {
+ long time = System.currentTimeMillis();
+ ScheduledFutureTask<?> s = queue.first();
+ if (s.time <= time) {
+ queue.remove(s);
+ Protocol.invokeLater(s);
+ }
+ else {
+ TCFDSFExecuter.this.wait(s.time - time);
+ }
+ }
+ }
+ }
+ catch (Throwable x) {
+ x.printStackTrace();
+ }
+ is_terminated = true;
+ }
+ }
+ });
+ thread.setName("TCF Future Task Scheduler");
+ thread.start();
+ }
+
+ public boolean isInExecutorThread() {
+ return Protocol.isDispatchThread();
+ }
+
+ public synchronized ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
+ if (command == null || unit == null) throw new NullPointerException();
+ if (is_shutdown) throw new RejectedExecutionException();
+ delay = unit.toMillis(delay);
+ ScheduledFutureTask<Boolean> s = new ScheduledFutureTask<Boolean>(delay, 0, command, Boolean.TRUE);
+ queue.add(s);
+ notify();
+ return s;
+ }
+
+ public synchronized <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
+ if (callable == null || unit == null) throw new NullPointerException();
+ if (is_shutdown) throw new RejectedExecutionException();
+ delay = unit.toMillis(delay);
+ ScheduledFutureTask<V> s = new ScheduledFutureTask<V>(delay, callable);
+ queue.add(s);
+ notify();
+ return s;
+ }
+
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
+ long initialDelay, long period, TimeUnit unit) {
+ if (command == null || unit == null) throw new NullPointerException();
+ if (is_shutdown) throw new RejectedExecutionException();
+ if (period <= 0) throw new RejectedExecutionException();
+ ScheduledFutureTask<Boolean> s = new ScheduledFutureTask<Boolean>(
+ unit.toMillis(initialDelay), unit.toMillis(period), command, Boolean.TRUE);
+ queue.add(s);
+ notify();
+ return s;
+ }
+
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
+ long initialDelay, long delay, TimeUnit unit) {
+ if (command == null || unit == null) throw new NullPointerException();
+ if (is_shutdown) throw new RejectedExecutionException();
+ if (delay <= 0) throw new RejectedExecutionException();
+ ScheduledFutureTask<Boolean> s = new ScheduledFutureTask<Boolean>(
+ unit.toMillis(initialDelay), -unit.toMillis(delay), command, Boolean.TRUE);
+ queue.add(s);
+ notify();
+ return s;
+ }
+
+ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+ thread.join(unit.toMillis(timeout));
+ return is_terminated;
+ }
+
+ public synchronized boolean isShutdown() {
+ return is_shutdown;
+ }
+
+ public synchronized boolean isTerminated() {
+ return is_terminated;
+ }
+
+ public synchronized void shutdown() {
+ is_shutdown = true;
+ notify();
+ }
+
+ public synchronized List<Runnable> shutdownNow() {
+ List<Runnable> res = new ArrayList<Runnable>(queue);
+ queue.clear();
+ is_shutdown = true;
+ notify();
+ return res;
+ }
+
+ public synchronized void execute(Runnable command) {
+ if (is_shutdown) throw new RejectedExecutionException();
+ Protocol.invokeLater(command);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java
new file mode 100644
index 000000000..b48b21853
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.launch;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.tcf.protocol.IChannel;
+
+
+public class TCFDSFLaunch extends TCFLaunch {
+
+ private final TCFDSFExecuter executor;
+ private final DsfSession session;
+
+ public TCFDSFLaunch(ILaunchConfiguration launchConfiguration, String mode) {
+ super(launchConfiguration, mode);
+ executor = new TCFDSFExecuter();
+ session = DsfSession.startSession(executor, ITCFConstants.ID_TCF_DEBUG_MODEL);
+ }
+
+ @Override
+ protected void runLaunchSequence(final Runnable done) {
+ super.runLaunchSequence(new Runnable() {
+ public void run() {
+ IChannel channel = getChannel();
+ if (channel != null) {
+ RequestMonitor monitor = new RequestMonitor(executor, null) {
+ @Override
+ protected void handleOK() {
+ done.run();
+ }
+ };
+ TCFDSFLaunchSequence seq = new TCFDSFLaunchSequence(session, TCFDSFLaunch.this, monitor);
+ executor.execute(seq);
+ }
+ else {
+ done.run();
+ }
+ }
+ });
+ }
+
+ public DsfExecutor getDsfExecutor() {
+ return executor;
+ }
+
+ public DsfSession getSession() {
+ return session;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchDelegate.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchDelegate.java
new file mode 100644
index 000000000..d6a9280bf
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchDelegate.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.launch;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+
+
+public class TCFDSFLaunchDelegate extends TCFLaunchDelegate {
+
+ public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
+ return new TCFDSFLaunch(configuration, mode);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java
new file mode 100644
index 000000000..b9c996085
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.launch;
+
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.concurrent.Sequence;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFBreakpoints;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFMemory;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFNativeProcesses;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRegisters;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControl;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFStack;
+import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFStepQueueManager;
+import org.eclipse.tm.tcf.protocol.IChannel;
+
+
+class TCFDSFLaunchSequence extends Sequence {
+
+ private final Step[] steps;
+
+ TCFDSFLaunchSequence(final DsfSession session, final TCFDSFLaunch launch, RequestMonitor monitor) {
+ super(session.getExecutor(), monitor);
+ final IChannel channel = launch.getChannel();
+ steps = new Step[] {
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFNativeProcesses(session, channel, monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFRunControl(session, channel, monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFStepQueueManager(session).initialize(monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFStack(session, channel, monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFMemory(session, channel, monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFRegisters(session, channel, monitor);
+ }
+ },
+ new Step() {
+ @Override
+ public void execute(RequestMonitor monitor) {
+ new TCFDSFBreakpoints(session, launch, monitor);
+ }
+ },
+ };
+ }
+
+ @Override
+ public Step[] getSteps() {
+ return steps;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java
new file mode 100644
index 000000000..d064448fe
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+public interface IDataRequest {
+
+ void cancel();
+ void done();
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java
new file mode 100644
index 000000000..ec723ed95
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.math.BigInteger;
+
+import org.eclipse.cdt.core.IAddress;
+
+public final class TCFAddress implements IAddress {
+
+ private final BigInteger addr;
+
+ public TCFAddress(Number addr) {
+ if (addr instanceof BigInteger) this.addr = (BigInteger)addr;
+ else this.addr = new BigInteger(addr.toString(), 10);
+ }
+
+ public IAddress add(BigInteger i) {
+ return new TCFAddress(addr.add(i));
+ }
+
+ public IAddress add(long l) {
+ if (l == 0) return this;
+ return new TCFAddress(addr.add(BigInteger.valueOf(l)));
+ }
+
+ public BigInteger distanceTo(IAddress a) {
+ return a.getValue().subtract(addr);
+ }
+
+ public int getCharsNum() {
+ // TODO don't know what getCharsNum() is supposed to return
+ return 0;
+ }
+
+ public BigInteger getMaxOffset() {
+ // TODO don't know what getMaxOffset() is supposed to return
+ return null;
+ }
+
+ public int getSize() {
+ // TODO don't know what getSize() is supposed to return
+ return 0;
+ }
+
+ public BigInteger getValue() {
+ return addr;
+ }
+
+ public boolean isMax() {
+ return false;
+ }
+
+ public boolean isZero() {
+ return addr.equals(BigInteger.ZERO);
+ }
+
+ public String toBinaryAddressString() {
+ return toHexAddressString();
+ }
+
+ public String toHexAddressString() {
+ return "0x" + toString(16);
+ }
+
+ public String toString(int radix) {
+ return addr.toString(radix);
+ }
+
+ public int compareTo(Object o) {
+ return addr.compareTo(((TCFAddress)o).addr);
+ }
+
+ public String toString() {
+ return "[" + toHexAddressString() + "]";
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java
new file mode 100644
index 000000000..6b1e00502
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.dd.dsf.service.IDsfService;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsModel;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.osgi.framework.BundleContext;
+
+
+// TODO IBreakpointHitEvent
+
+public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IBreakpoints {
+
+ private class BreakpointDMC extends AbstractDMContext implements IBreakpointDMContext {
+
+ final String id;
+ final IBreakpoint bp;
+ final TCFDataCache<Map<String,Object>> status;
+
+ boolean disposed;
+
+ public BreakpointDMC(IDsfService service, final String id, IBreakpoint bp) {
+ super(service, new IDMContext[0]);
+ this.id = id;
+ this.bp = bp;
+ cache.put(id, this);
+ status = new TCFDataCache<Map<String,Object>>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ assert !disposed;
+ if (tcf_bpt_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_bpt_service.getStatus(id, new org.eclipse.tm.tcf.services.IBreakpoints.DoneGetStatus() {
+ public void doneGetStatus(IToken token, Exception err, Map<String,Object> status) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ data = status;
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return super.baseEquals(other) && ((BreakpointDMC)other).id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ void dispose() {
+ assert !disposed;
+ cache.remove(id);
+ disposed = true;
+ }
+ }
+
+ private class BreakpointData implements IBreakpointDMData {
+
+ final IBreakpoint bp;
+ final BreakpointStatus status;
+
+ BreakpointData(IBreakpoint bp, BreakpointStatus status) {
+ this.bp = bp;
+ this.status = status;
+ }
+
+ public IBreakpoint getPlatformBreakpoint() {
+ return bp;
+ }
+
+ public BreakpointStatus getStatus() {
+ return status;
+ }
+ }
+
+ private final ITCFBreakpointListener bp_listener = new ITCFBreakpointListener() {
+
+ public void breakpointStatusChanged(String id) {
+ final BreakpointDMC dmc = cache.get(id);
+ if (dmc != null) {
+ Map<String, Object> map = launch.getBreakpointsStatus().getStatus(dmc.id);
+ dmc.status.reset(map);
+ IBreakpointDMEvent e = null;
+ if (map == null) {
+ e = new IBreakpointUninstalledDMEvent() {
+ public IBreakpointDMContext getDMContext() {
+ return dmc;
+ }
+ };
+ }
+ else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_ERROR) != null) {
+ e = new IBreakpointInstallFailedDMEvent() {
+ public IBreakpointDMContext getDMContext() {
+ return dmc;
+ }
+ };
+ }
+ else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_PLANTED) != null) {
+ e = new IBreakpointInstalledDMEvent() {
+ public IBreakpointDMContext getDMContext() {
+ return dmc;
+ }
+ };
+ }
+ else {
+ e = new IBreakpointUninstalledDMEvent() {
+ public IBreakpointDMContext getDMContext() {
+ return dmc;
+ }
+ };
+ }
+ getSession().dispatchEvent(e, getProperties());
+ }
+ }
+
+ public void breakpointRemoved(String id) {
+ final BreakpointDMC dmc = cache.get(id);
+ if (dmc != null) {
+ dmc.dispose();
+ IBreakpointDMEvent e = new IBreakpointUninstalledDMEvent() {
+ public IBreakpointDMContext getDMContext() {
+ return dmc;
+ }
+ };
+ getSession().dispatchEvent(e, getProperties());
+ }
+ }
+ };
+
+ private final TCFLaunch launch;
+ private final IChannel channel;
+ private final org.eclipse.tm.tcf.services.IBreakpoints tcf_bpt_service;
+ private final Map<String,BreakpointDMC> cache = new HashMap<String,BreakpointDMC>();
+
+ public TCFDSFBreakpoints(DsfSession session, TCFLaunch launch, final RequestMonitor monitor) {
+ super(session);
+ this.launch = launch;
+ channel = launch.getChannel();
+ launch.getBreakpointsStatus().addListener(bp_listener);
+ tcf_bpt_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IBreakpoints.class);
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ org.eclipse.dd.dsf.debug.service.IBreakpoints.class.getName(),
+ TCFDSFBreakpoints.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public void getAllBreakpoints(IDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm) {
+ IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager();
+ TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel();
+ IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL);
+ ArrayList<IBreakpointDMContext> l = new ArrayList<IBreakpointDMContext>();
+ if (arr != null && arr.length == 0) {
+ for (IBreakpoint bp : arr) {
+ if (m.isSupported(channel, bp)) {
+ IMarker marker = bp.getMarker();
+ String id = marker.getAttribute(ITCFConstants.ID_TCF_DEBUG_MODEL +
+ '.' + org.eclipse.tm.tcf.services.IBreakpoints.PROP_ID, (String)null);
+ if (id != null) {
+ BreakpointDMC c = cache.get(id);
+ if (c == null) c = new BreakpointDMC(this, id, bp);
+ l.add(c);
+ }
+ }
+ }
+ }
+ rm.setData(l.toArray(new IBreakpointDMContext[l.size()]));
+ rm.done();
+ }
+
+ public void getBreakpoints(IDMContext dmc, IBreakpoint bp, DataRequestMonitor<IBreakpointDMContext[]> rm) {
+ TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel();
+ ArrayList<IBreakpointDMContext> l = new ArrayList<IBreakpointDMContext>();
+ if (m.isSupported(channel, bp)) {
+ IMarker marker = bp.getMarker();
+ String id = marker.getAttribute(ITCFConstants.ID_TCF_DEBUG_MODEL +
+ '.' + org.eclipse.tm.tcf.services.IBreakpoints.PROP_ID, (String)null);
+ if (id != null) {
+ BreakpointDMC c = cache.get(id);
+ if (c == null) c = new BreakpointDMC(this, id, bp);
+ l.add(c);
+ }
+ }
+ rm.setData(l.toArray(new IBreakpointDMContext[l.size()]));
+ rm.done();
+ }
+
+ public void getBreakpointData(final IDMContext dmc, final DataRequestMonitor<IBreakpointDMData> rm) {
+ if (dmc instanceof BreakpointDMC) {
+ BreakpointDMC bp = (BreakpointDMC)dmc;
+ if (!bp.status.validate()) {
+ bp.status.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getBreakpointData(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (bp.status.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", bp.status.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ Map<String,Object> map = bp.status.getData();
+ BreakpointStatus status = BreakpointStatus.FILTERED_OUT;
+ if (map != null) {
+ if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_ERROR) != null) {
+ status = BreakpointStatus.FAILED_TO_INSTALL;
+ }
+ else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_PLANTED) != null) {
+ status = BreakpointStatus.INSTALLED;
+ }
+ }
+ rm.setData(new BreakpointData(bp.bp, status));
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+ if (dmc instanceof BreakpointDMC) {
+ getBreakpointData((BreakpointDMC)dmc, (DataRequestMonitor<IBreakpointDMData>)rm);
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java
new file mode 100644
index 000000000..6246cd99d
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.dd.dsf.service.IDsfService;
+
+public abstract class TCFDSFExecutionDMC extends AbstractDMContext implements IExecutionDMContext, IContainerDMContext {
+
+ interface DataCache {
+ }
+
+ DataCache stack_frames_cache;
+ DataCache memory_cache;
+ DataCache registers_cache;
+
+ TCFDSFExecutionDMC(IDsfService service, IDMContext[] parents) {
+ super(service, parents);
+ }
+
+ /**
+ * Get TCF ID of execution context.
+ * @return TCF ID.
+ */
+ public abstract String getTcfContextId();
+
+ /**
+ * Check if this context object is disposed, because, for example, a thread has exited.
+ * @return true if context object is disposed.
+ */
+ public abstract boolean isDisposed();
+
+ /**
+ * Validate execution state data.
+ * @return true if state is valid, false if data retrieval is started.
+ */
+ public abstract boolean validateState();
+
+ /**
+ * Add a listener to be activated when state data retrieval is done.
+ * @param req - listener object.
+ */
+ public abstract void addStateWaitingRequest(IDataRequest req);
+
+ /**
+ * Get current program counter. This method must be called only when
+ * execution state data is valid - when validateState() return true.
+ * @return current program counter address.
+ */
+ public abstract TCFAddress getPC();
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java
new file mode 100644
index 000000000..cf40d6a4b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.Hashtable;
+
+import org.eclipse.cdt.core.IAddress;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IMemory.MemoryContext;
+import org.eclipse.tm.tcf.services.IMemory.MemoryError;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IMemory {
+
+ private class MemoryCache implements TCFDSFExecutionDMC.DataCache {
+
+ final TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext> context;
+
+ MemoryCache(final IChannel channel, final TCFDSFExecutionDMC exe) {
+ context = new TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ String id = exe.getTcfContextId();
+ if (id == null || tcf_mem_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_mem_service.getContext(id,
+ new org.eclipse.tm.tcf.services.IMemory.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception err,
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext ctx) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ error = err;
+ }
+ else {
+ data = ctx;
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ }
+ }
+
+ private final org.eclipse.tm.tcf.services.IMemory.MemoryListener mem_listener =
+ new org.eclipse.tm.tcf.services.IMemory.MemoryListener() {
+
+ public void contextAdded(MemoryContext[] contexts) {
+ }
+
+ public void contextChanged(MemoryContext[] contexts) {
+ }
+
+ public void contextRemoved(String[] context_ids) {
+ }
+
+ public void memoryChanged(String context_id, Number[] addr, long[] size) {
+ TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class);
+ TCFDSFExecutionDMC exe = rc.getContext(context_id);
+ if (exe == null || exe.memory_cache == null) return;
+ for (int n = 0; n < addr.length; n++) {
+ long count = size[n];
+ // TODO: DSF does not support address ranges
+ if (count > 256) count = 256;
+ IAddress[] addresses = new IAddress[(int)count];
+ for (int i = 0; i < (int)count; i++) {
+ addresses[i] = new TCFAddress(addr[n]).add(i);
+ }
+ getSession().dispatchEvent(new MemoryChangedEvent(exe, addresses), getProperties());
+ }
+ }
+ };
+
+ private final IChannel channel;
+ private final org.eclipse.tm.tcf.services.IMemory tcf_mem_service;
+
+ public TCFDSFMemory(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ this.channel = channel;
+ tcf_mem_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IMemory.class);
+ if (tcf_mem_service != null) tcf_mem_service.addListener(mem_listener);
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ org.eclipse.dd.dsf.debug.service.IMemory.class.getName(),
+ TCFDSFMemory.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public void fillMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final byte[] pattern, final RequestMonitor rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ fillMemory(dmc, address, offset, word_size, count, pattern, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ mem.fill(address.add(offset).getValue(), word_size, pattern, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getMemory(dmc, address, offset, word_size, count, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ final byte[] buffer = new byte[word_size * count];
+ mem.get(address.add(offset).getValue(), word_size, buffer, 0, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ MemoryByte[] res = new MemoryByte[buffer.length];
+ for (int i = 0; i < buffer.length; i++) {
+ res[i] = new MemoryByte(buffer[i]);
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void setMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final byte[] buffer, final RequestMonitor rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ setMemory(dmc, address, offset, word_size, count, buffer, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ mem.set(address.add(offset).getValue(), word_size, buffer, 0, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java
new file mode 100644
index 000000000..b1f66dde4
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java
@@ -0,0 +1,614 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.datamodel.ServiceDMContext;
+import org.eclipse.dd.dsf.debug.service.INativeProcesses;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IProcesses;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IProcesses.ProcessContext;
+import org.eclipse.tm.tcf.services.IRunControl.RunControlContext;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFNativeProcesses extends AbstractDsfService implements INativeProcesses {
+
+ private class ProcessDMC extends TCFDSFProcessDMC implements IProcessDMContext {
+
+ final String id;
+
+ ProcessDMC(String id, IDMContext parent) {
+ super(TCFDSFNativeProcesses.this, parent != null ? new IDMContext[]{ parent } : new IDMContext[0]);
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!super.baseEquals(obj)) return false;
+ String obj_id = ((ProcessDMC)obj).id;
+ if (obj_id == null) return id == null;
+ return obj_id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ if (id == null) return 0;
+ return id.hashCode();
+ }
+ }
+
+ private class ThreadDMC extends TCFDSFThreadDMC implements IThreadDMContext {
+
+ final String id;
+
+ ThreadDMC(String id) {
+ super(TCFDSFNativeProcesses.this, new IDMContext[0]);
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!super.baseEquals(obj)) return false;
+ String obj_id = ((ThreadDMC)obj).id;
+ if (obj_id == null) return id == null;
+ return obj_id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+ }
+
+ private class ProcessData implements IProcessDMData {
+
+ private final IProcesses.ProcessContext ctx;
+
+ ProcessData(IProcesses.ProcessContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public IDMContext getDebugContext() {
+ return getServicesTracker().getService(TCFDSFRunControl.class).getContext(ctx.getID());
+ }
+
+ public String getId() {
+ return ctx.getID();
+ }
+
+ public String getName() {
+ return ctx.getName();
+ }
+
+ public boolean isDebuggerAttached() {
+ return ctx.isAttached();
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+ }
+
+ private class ThreadData implements IThreadDMData {
+
+ private final TCFDSFExecutionDMC ctx;
+
+ ThreadData(TCFDSFExecutionDMC ctx) {
+ this.ctx = ctx;
+ }
+
+ public IDMContext getDebugContext() {
+ return ctx;
+ }
+
+ public String getId() {
+ if (ctx == null) return null;
+ return ctx.getTcfContextId();
+ }
+
+ public String getName() {
+ // TODO thread name
+ return "";
+ }
+
+ public boolean isDebuggerAttached() {
+ return true;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+ }
+
+ private class ProcessStartedEvent extends AbstractDMEvent<IDMContext> implements IProcessStartedEvent {
+
+ private final IProcessDMContext prs;
+
+ ProcessStartedEvent(IDMContext dmc, IProcessDMContext prs) {
+ super(dmc);
+ this.prs = prs;
+ }
+
+ public IProcessDMContext getProcess() {
+ return prs;
+ }
+ }
+
+ private class ProcessExitedEvent extends AbstractDMEvent<IDMContext> implements IProcessExitedEvent {
+
+ private final IProcessDMContext prs;
+
+ ProcessExitedEvent(IDMContext dmc, IProcessDMContext prs) {
+ super(dmc);
+ this.prs = prs;
+ }
+
+ public IProcessDMContext getProcess() {
+ return prs;
+ }
+ }
+
+ private final org.eclipse.tm.tcf.services.IRunControl.RunControlListener run_listener =
+ new org.eclipse.tm.tcf.services.IRunControl.RunControlListener() {
+
+ public void containerResumed(String[] context_ids) {
+ }
+
+ public void containerSuspended(String context, String pc,
+ String reason, Map<String, Object> params,
+ String[] suspended_ids) {
+ }
+
+ public void contextAdded(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ String id = ctx.getID();
+ if (id.equals(ctx.getProperties().get(IRunControl.PROP_PROCESS_ID))) {
+ ProcessDMC dmc = new ProcessDMC(id, root_dmc);
+ process_cache.put(id, dmc);
+ getSession().dispatchEvent(new ProcessStartedEvent(root_dmc, dmc), getProperties());
+ }
+ else {
+ ThreadDMC dmc = new ThreadDMC(id);
+ thread_cache.put(id, dmc);
+ }
+ }
+ }
+
+ public void contextChanged(RunControlContext[] contexts) {
+ }
+
+ public void contextException(String context, String msg) {
+ }
+
+ public void contextRemoved(String[] context_ids) {
+ for (String id : context_ids) {
+ ProcessDMC dmc = process_cache.remove(id);
+ if (dmc != null) {
+ getSession().dispatchEvent(new ProcessExitedEvent(root_dmc, dmc), getProperties());
+ }
+ else {
+ thread_cache.remove(id);
+ }
+ }
+ }
+
+ public void contextResumed(String context) {
+ }
+
+ public void contextSuspended(String context, String pc,
+ String reason, Map<String, Object> params) {
+ }
+ };
+
+ private final IProcesses tcf_prs_service;
+ private final org.eclipse.tm.tcf.services.IRunControl tcf_run_service;
+ private final Map<String,ProcessDMC> process_cache = new HashMap<String,ProcessDMC>(); // all attached processes
+ private final Map<String,ThreadDMC> thread_cache = new HashMap<String,ThreadDMC>(); // only some of attached threads
+ private final ProcessDMC root_dmc = new ProcessDMC(null, null);
+ private IDMContext service_dmc;
+
+ public TCFDSFNativeProcesses(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ tcf_prs_service = channel.getRemoteService(IProcesses.class);
+ tcf_run_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IRunControl.class);
+ if (tcf_run_service != null) tcf_run_service.addListener(run_listener);
+ service_dmc = new ServiceDMContext(this, "#native_process");
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ INativeProcesses.class.getName(),
+ TCFDSFNativeProcesses.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void initialize(final RequestMonitor monitor) {
+ final Collection<String> list = new ArrayList<String>();
+ final Set<IToken> cmds = new HashSet<IToken>();
+ final IProcesses.DoneGetChildren done = new IProcesses.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ if (cmds.isEmpty()) return;
+ assert cmds.contains(token);
+ cmds.remove(token);
+ if (error != null) {
+ for (IToken t : cmds) t.cancel();
+ cmds.clear();
+ monitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ monitor.done();
+ }
+ else {
+ for (String id : context_ids) {
+ list.add(id);
+ cmds.add(tcf_prs_service.getChildren(id, true, this));
+ }
+ if (cmds.isEmpty()) {
+ for (String id : list) {
+ assert id != null;
+ if (process_cache.get(id) != null) continue;
+ process_cache.put(id, new ProcessDMC(id, root_dmc));
+ }
+ process_cache.put(null, root_dmc);
+ TCFDSFNativeProcesses.super.initialize(monitor);
+ }
+ }
+ }
+ };
+ cmds.add(tcf_prs_service.getChildren(null, true, done));
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public IDMContext getServiceContext() {
+ return service_dmc;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public void attachDebuggerToProcess(IProcessDMContext ctx, final RequestMonitor rm) {
+ if (tcf_prs_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (ctx instanceof ProcessDMC) {
+ final ProcessDMC p = (ProcessDMC)ctx;
+ tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (context == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ context.attach(new IProcesses.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot attach a process", error)); //$NON-NLS-1$
+ }
+ assert error != null || process_cache.get(p.id) != null;
+ rm.done();
+ }
+ });
+ }
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void canTerminate(IDMContext ctx, final DataRequestMonitor<Boolean> rm) {
+ rm.setData(false);
+ if (tcf_prs_service == null) {
+ rm.done();
+ }
+ else if (ctx instanceof ProcessDMC) {
+ ProcessDMC p = (ProcessDMC)ctx;
+ tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$
+ }
+ else if (context == null) {
+ rm.setData(false);
+ }
+ else {
+ rm.setData(context.canTerminate());
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void terminate(IDMContext ctx, final RequestMonitor rm) {
+ if (tcf_prs_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (ctx instanceof ProcessDMC) {
+ ProcessDMC p = (ProcessDMC)ctx;
+ tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (context == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ context.terminate(new IProcesses.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot terminate a process", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ }
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void debugNewProcess(String file, final DataRequestMonitor<IProcessDMContext> rm) {
+ if (tcf_prs_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ tcf_prs_service.start(null, file, null, null, true, new IProcesses.DoneStart() {
+ public void doneStart(IToken token, Exception error, ProcessContext process) {
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot start a process", error)); //$NON-NLS-1$
+ }
+ else {
+ ProcessDMC dmc = process_cache.get(process.getID());
+ assert dmc != null;
+ rm.setData(dmc);
+ }
+ rm.done();
+ }
+ });
+ }
+ }
+
+ public void runNewProcess(String file, final DataRequestMonitor<IProcessDMContext> rm) {
+ if (tcf_prs_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ tcf_prs_service.start(null, file, null, null, false, new IProcesses.DoneStart() {
+ public void doneStart(IToken token, Exception error, ProcessContext process) {
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot start a process", error)); //$NON-NLS-1$
+ }
+ else {
+ assert process_cache.get(process.getID()) == null;
+ rm.setData(new ProcessDMC(process.getID(), root_dmc));
+ }
+ rm.done();
+ }
+ });
+ }
+ }
+
+ public IProcessDMContext getProcessForDebugContext(IDMContext ctx) {
+ if (ctx instanceof IProcessDMContext) {
+ return (IProcessDMContext)ctx;
+ }
+ if (ctx instanceof TCFDSFExecutionDMC) {
+ String id = ((TCFDSFExecutionDMC)ctx).getTcfContextId();
+ return process_cache.get(id);
+ }
+ return null;
+ }
+
+ public IThreadDMContext getThreadForDebugContext(IDMContext ctx) {
+ if (ctx instanceof IThreadDMContext) {
+ return (IThreadDMContext)ctx;
+ }
+ if (ctx instanceof TCFDSFExecutionDMC) {
+ String id = ((TCFDSFExecutionDMC)ctx).getTcfContextId();
+ ThreadDMC dmc = thread_cache.get(id);
+ if (dmc == null) dmc = new ThreadDMC(id);
+ return dmc;
+ }
+ return null;
+ }
+
+ public void getProcessesBeingDebugged(DataRequestMonitor<IProcessDMContext[]> rm) {
+ rm.setData(process_cache.values().toArray(new IProcessDMContext[process_cache.size()]));
+ rm.done();
+ }
+
+ public void getRunningProcesses(final DataRequestMonitor<IProcessDMContext[]> rm) {
+ final Collection<String> list = new ArrayList<String>();
+ final Set<IToken> cmds = new HashSet<IToken>();
+ final IProcesses.DoneGetChildren done = new IProcesses.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ if (cmds.isEmpty()) return;
+ assert cmds.contains(token);
+ cmds.remove(token);
+ if (error != null) {
+ for (IToken t : cmds) t.cancel();
+ cmds.clear();
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ for (String id : context_ids) {
+ list.add(id);
+ cmds.add(tcf_prs_service.getChildren(id, false, this));
+ }
+ if (cmds.isEmpty()) {
+ int cnt = 0;
+ IProcessDMContext[] data = new IProcessDMContext[list.size()];
+ for (String id : list) {
+ assert id != null;
+ data[cnt] = process_cache.get(id);
+ if (data[cnt] == null) data[cnt] = new ProcessDMC(id, root_dmc);
+ cnt++;
+ }
+ rm.setData(data);
+ rm.done();
+ }
+ }
+ }
+ };
+ cmds.add(tcf_prs_service.getChildren(null, false, done));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void getModelData(IDMContext dmc, final DataRequestMonitor<?> rm) {
+ if (dmc instanceof ProcessDMC) {
+ getProcessData((ProcessDMC)dmc, (DataRequestMonitor<IProcessDMData>)rm);
+ }
+ else if (dmc instanceof ThreadDMC) {
+ getThreadData((ThreadDMC)dmc, (DataRequestMonitor<IThreadDMData>)rm);
+ }
+ else if (dmc == service_dmc) {
+ ((DataRequestMonitor<TCFDSFNativeProcesses>)rm).setData(this);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getProcessData(IProcessDMContext dmc, final DataRequestMonitor<IProcessDMData> rm) {
+ if (dmc instanceof ProcessDMC) {
+ tcf_prs_service.getContext(((ProcessDMC)dmc).id, new IProcesses.DoneGetContext() {
+
+ @SuppressWarnings("unchecked")
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$
+ }
+ else if (context == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$
+ }
+ else {
+ rm.setData(new ProcessData(context));
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getThreadData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
+ if (dmc instanceof ThreadDMC) {
+ String id = ((ThreadDMC)dmc).id;
+ TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class);
+ rm.setData(new ThreadData(rc.getContext(id)));
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java
new file mode 100644
index 000000000..8dacf0692
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.INativeProcesses.IProcessDMContext;
+import org.eclipse.dd.dsf.service.IDsfService;
+
+public abstract class TCFDSFProcessDMC extends AbstractDMContext implements IProcessDMContext {
+
+ TCFDSFProcessDMC(IDsfService service, IDMContext[] parents) {
+ super(service, parents);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java
new file mode 100644
index 000000000..1614118c3
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java
@@ -0,0 +1,1060 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRegisters.DoneGet;
+import org.eclipse.tm.tcf.services.IRegisters.DoneSet;
+import org.eclipse.tm.tcf.services.IRegisters.NamedValue;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IRegisters {
+
+ private class ObjectDMC extends AbstractDMContext implements IFormattedDataDMContext {
+
+ final String id;
+ final RegistersCache children;
+ final Map<String,ValueDMC> values;
+
+ org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
+ boolean disposed;
+
+ ObjectDMC(String session_id, IDMContext[] parents, String id) {
+ super(session_id, parents);
+ this.id = id;
+ children = new RegistersCache(channel, id, new IDMContext[]{ this });
+ values = new HashMap<String,ValueDMC>();
+ model.put(id, this);
+ }
+
+ ObjectDMC(String session_id, IDMContext[] parents, String id, RegistersCache children) {
+ super(session_id, parents);
+ this.id = id;
+ this.children = children;
+ values = new HashMap<String,ValueDMC>();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return super.baseEquals(other) && ((ObjectDMC)other).id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ public String getName() {
+ return context.getName();
+ }
+
+ void dispose() {
+ assert !disposed;
+ children.dispose();
+ for (ValueDMC v : values.values()) v.dispose();
+ values.clear();
+ model.remove(id);
+ disposed = true;
+ }
+ }
+
+ private class RegisterGroupDMC extends ObjectDMC implements IRegisterGroupDMContext {
+
+ RegisterGroupDMC(String session_id, IDMContext[] parents, String id) {
+ super(session_id, parents, id);
+ }
+
+ /* Constructor for a fake register group - DSF requires at least one group object */
+ RegisterGroupDMC(String session_id, IDMContext[] parents, final String id, RegistersCache children) {
+ super(session_id, parents, id, children);
+ context = new org.eclipse.tm.tcf.services.IRegisters.RegistersContext() {
+ public String[] getAvailableFormats() {
+ return null;
+ }
+ public int[] getBitNumbers() {
+ return null;
+ }
+ public String getDescription() {
+ return null;
+ }
+ public int getFirstBitNumber() {
+ return 0;
+ }
+ public String getID() {
+ return id;
+ }
+ public String getName() {
+ return null;
+ }
+ public NamedValue[] getNamedValues() {
+ return null;
+ }
+ public String getParentID() {
+ return null;
+ }
+ public Map<String, Object> getProperties() {
+ return null;
+ }
+ public boolean hasSideEffects() {
+ return false;
+ }
+ public boolean isBigEndian() {
+ return false;
+ }
+ public boolean isFloat() {
+ return false;
+ }
+ public boolean isLeftToRight() {
+ return false;
+ }
+ public boolean isReadOnce() {
+ return false;
+ }
+ public boolean isReadable() {
+ return false;
+ }
+ public boolean isVolatile() {
+ return false;
+ }
+ public boolean isWriteOnce() {
+ return false;
+ }
+ public boolean isWriteable() {
+ return false;
+ }
+ public IToken get(String format, DoneGet done) {
+ throw new Error();
+ }
+ public IToken set(String format, String value, DoneSet done) {
+ throw new Error();
+ }
+ };
+ }
+ }
+
+ private class RegisterDMC extends ObjectDMC implements IRegisterDMContext {
+
+ RegisterDMC(String session_id, IDMContext[] parents, String id) {
+ super(session_id, parents, id);
+ }
+ }
+
+ private class BitFieldDMC extends ObjectDMC implements IBitFieldDMContext {
+
+ BitFieldDMC(String session_id, IDMContext[] parents, String id) {
+ super(session_id, parents, id);
+ }
+ }
+
+ private class ValueDMC extends FormattedValueDMContext {
+
+ final RegisterValueCache cache;
+
+ boolean disposed;
+
+ ValueDMC(ObjectDMC parent, String fmt) {
+ super(TCFDSFRegisters.this, parent, fmt);
+ cache = new RegisterValueCache(channel, parent.context, fmt);
+ }
+
+ void dispose() {
+ assert !disposed;
+ cache.dispose();
+ disposed = true;
+ }
+ }
+
+ private class RegisterGroupData implements IRegisterGroupDMData {
+
+ final org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
+
+ RegisterGroupData(org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) {
+ this.context = context;
+ }
+
+ public String getDescription() {
+ return context.getDescription();
+ }
+
+ public String getName() {
+ return context.getName();
+ }
+ }
+
+ private class RegisterData implements IRegisterDMData {
+
+ final org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
+
+ RegisterData(org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) {
+ this.context = context;
+ }
+
+ public String getDescription() {
+ return context.getDescription();
+ }
+
+ public String getName() {
+ return context.getName();
+ }
+
+ public boolean hasSideEffects() {
+ return context.hasSideEffects();
+ }
+
+ public boolean isFloat() {
+ return context.isFloat();
+ }
+
+ public boolean isReadOnce() {
+ return context.isReadOnce();
+ }
+
+ public boolean isReadable() {
+ return context.isReadable();
+ }
+
+ public boolean isVolatile() {
+ return context.isVolatile();
+ }
+
+ public boolean isWriteOnce() {
+ return context.isWriteOnce();
+ }
+
+ public boolean isWriteable() {
+ return context.isWriteable();
+ }
+ }
+
+ private class BitFieldData implements IBitFieldDMData {
+
+ final org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
+
+ IMnemonic[] mnemonics;
+ IBitGroup[] bit_groups;
+
+ BitFieldData(org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) {
+ this.context = context;
+ }
+
+ public IBitGroup[] getBitGroup() {
+ if (bit_groups == null) {
+ int[] arr = context.getBitNumbers();
+ if (arr == null) {
+ bit_groups = new IBitGroup[0];
+ }
+ else {
+ Arrays.sort(arr);
+ ArrayList<IBitGroup> l = new ArrayList<IBitGroup>();
+ int i = 0;
+ while (i < arr.length) {
+ int j = i;
+ while (j + 1 < arr.length && arr[j + 1] == arr[j] + 1) j++;
+ final int i0 = i;
+ final int i1 = j;
+ l.add(new IBitGroup() {
+ public int bitCount() {
+ return i1 - i0 + 1;
+ }
+ public int startBit() {
+ return i0;
+ }
+ });
+ i = j + 1;
+ }
+ bit_groups = l.toArray(new IBitGroup[l.size()]);
+ }
+ }
+ return bit_groups;
+ }
+
+ public IMnemonic getCurrentMnemonicValue() {
+ // TODO getCurrentMnemonicValue() should be async
+ return null;
+ }
+
+ public String getDescription() {
+ return context.getDescription();
+ }
+
+ public IMnemonic[] getMnemonics() {
+ if (mnemonics == null) {
+ NamedValue[] arr = context.getNamedValues();
+ if (arr == null) {
+ mnemonics = new IMnemonic[0];
+ }
+ else {
+ int cnt = 0;
+ mnemonics = new IMnemonic[arr.length];
+ for (final NamedValue v : arr) {
+ mnemonics[cnt++] = new IMnemonic() {
+ public String getLongName() {
+ return v.getDescription();
+ }
+ public String getShortName() {
+ return v.getName();
+ }
+ };
+ }
+ }
+ }
+ return mnemonics;
+ }
+
+ public String getName() {
+ return context.getName();
+ }
+
+ public boolean hasSideEffects() {
+ return context.hasSideEffects();
+ }
+
+ public boolean isReadOnce() {
+ return context.isReadOnce();
+ }
+
+ public boolean isReadable() {
+ return context.isReadable();
+ }
+
+ public boolean isWriteOnce() {
+ return context.isWriteOnce();
+ }
+
+ public boolean isWriteable() {
+ return context.isWriteable();
+ }
+
+ public boolean isZeroBasedNumbering() {
+ return context.getFirstBitNumber() == 0;
+ }
+
+ public boolean isZeroBitLeftMost() {
+ return context.isLeftToRight();
+ }
+ }
+
+ private class RegistersCache extends TCFDataCache<Map<String,ObjectDMC>>
+ implements TCFDSFExecutionDMC.DataCache {
+
+ final String id;
+ final IDMContext[] parents;
+
+ boolean disposed;
+
+ public RegistersCache(IChannel channel, String id, IDMContext[] parents) {
+ super(channel);
+ this.id = id;
+ this.parents = parents;
+ }
+
+ void invalidateRegContents() {
+ if (data == null) return;
+ for (ObjectDMC dmc : data.values()) {
+ for (ValueDMC val : dmc.values.values()) val.cache.reset();
+ dmc.children.invalidateRegContents();
+ }
+ }
+
+ void dispose() {
+ assert !disposed;
+ if (data != null) {
+ for (ObjectDMC dmc : data.values()) dmc.dispose();
+ }
+ reset();
+ disposed = true;
+ }
+
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ assert !disposed;
+ if (tcf_reg_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_reg_service.getChildren(id, new org.eclipse.tm.tcf.services.IRegisters.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception err, String[] contexts) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ data = new LinkedHashMap<String,ObjectDMC>();
+ if (contexts.length > 0) {
+ // TODO DSF service design does not support lazy retrieval of context attributes (because getName() is not async)
+ final Set<IToken> cmds = new HashSet<IToken>();
+ final IToken cb = new IToken() {
+ public boolean cancel() {
+ for (IToken x : cmds) x.cancel();
+ return false;
+ }
+ };
+ command = cb;
+ org.eclipse.tm.tcf.services.IRegisters.DoneGetContext done = new org.eclipse.tm.tcf.services.IRegisters.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception err,
+ org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) {
+ cmds.remove(token);
+ if (command != cb) return;
+ if (err != null) {
+ command.cancel();
+ command = null;
+ data = null;
+ error = err;
+ valid = true;
+ validate();
+ return;
+ }
+ String id = context.getID();
+ ObjectDMC dmc = null;
+ if (context.getBitNumbers() != null) {
+ dmc = new BitFieldDMC(getSession().getId(), parents, id);
+ }
+ else if (context.isReadable() || context.isWriteable()) {
+ dmc = new RegisterDMC(getSession().getId(), parents, id);
+ }
+ else {
+ dmc = new RegisterGroupDMC(getSession().getId(), parents, id);
+ }
+ dmc.context = context;
+ data.put(id, dmc);
+ if (cmds.isEmpty()) {
+ command = null;
+ valid = true;
+ validate();
+ }
+ }
+ };
+ for (String id : contexts) {
+ cmds.add(tcf_reg_service.getContext(id, done));
+ }
+ return;
+ }
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ }
+
+ private class RegisterValueCache extends TCFDataCache<FormattedValueDMData> {
+
+ final org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
+ final String fmt;
+
+ boolean disposed;
+
+ public RegisterValueCache(IChannel channel,
+ org.eclipse.tm.tcf.services.IRegisters.RegistersContext context, String fmt) {
+ super(channel);
+ this.context = context;
+ this.fmt = fmt;
+ }
+
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ assert tcf_reg_service != null;
+ assert context != null;
+ assert !disposed;
+ command = context.get(fmt, new org.eclipse.tm.tcf.services.IRegisters.DoneGet() {
+ public void doneGet(IToken token, Exception err, String value) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ data = new FormattedValueDMData(value);
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+
+ void dispose() {
+ assert !disposed;
+ reset();
+ disposed = true;
+ }
+ }
+
+ private static class RegisterGroupChangedEvent extends AbstractDMEvent<IRegisterGroupDMContext>
+ implements IGroupChangedDMEvent {
+
+ public RegisterGroupChangedEvent(IRegisterGroupDMContext context) {
+ super(context);
+ }
+ }
+
+ private static class RegisterChangedEvent extends AbstractDMEvent<IRegisterDMContext>
+ implements IRegisterChangedDMEvent {
+
+ public RegisterChangedEvent(IRegisterDMContext context) {
+ super(context);
+ }
+ }
+
+ private static class BitFieldChangedEvent extends AbstractDMEvent<IBitFieldDMContext>
+ implements IBitFieldChangedDMEvent {
+
+ public BitFieldChangedEvent(IBitFieldDMContext context) {
+ super(context);
+ }
+ }
+
+ private static class GroupsChangedEvent
+ extends AbstractDMEvent<org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext>
+ implements IGroupsChangedDMEvent {
+
+ public GroupsChangedEvent(IExecutionDMContext context) {
+ super(context);
+ }
+ }
+
+ private final org.eclipse.tm.tcf.services.IRegisters.RegistersListener listener =
+ new org.eclipse.tm.tcf.services.IRegisters.RegistersListener() {
+
+ public void contextChanged() {
+ TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class);
+ for (TCFDSFExecutionDMC dmc : rc.getCachedContexts()) {
+ RegistersCache c = (RegistersCache)dmc.registers_cache;
+ if (c != null) {
+ c.dispose();
+ dmc.registers_cache = null;
+ getSession().dispatchEvent(new GroupsChangedEvent(dmc), getProperties());
+ }
+ }
+ }
+
+ public void registerChanged(String id) {
+ ObjectDMC dmc = model.get(id);
+ if (dmc != null) {
+ for (ValueDMC val : dmc.values.values()) val.cache.reset();
+ dmc.children.invalidateRegContents();
+ if (dmc instanceof RegisterGroupDMC) {
+ getSession().dispatchEvent(new RegisterGroupChangedEvent((RegisterGroupDMC)dmc), getProperties());
+ }
+ else if (dmc instanceof RegisterDMC) {
+ getSession().dispatchEvent(new RegisterChangedEvent((RegisterDMC)dmc), getProperties());
+ }
+ else if (dmc instanceof BitFieldDMC) {
+ getSession().dispatchEvent(new BitFieldChangedEvent((BitFieldDMC)dmc), getProperties());
+ }
+ }
+ }
+ };
+
+ private final IChannel channel;
+ private final org.eclipse.tm.tcf.services.IRegisters tcf_reg_service;
+ private final Map<String,ObjectDMC> model;
+
+ public TCFDSFRegisters(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ this.channel = channel;
+ model = new HashMap<String,ObjectDMC>();
+ tcf_reg_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IRegisters.class);
+ if (tcf_reg_service != null) tcf_reg_service.addListener(listener);
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ org.eclipse.dd.dsf.debug.service.IRegisters.class.getName(),
+ TCFDSFRegisters.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ getSession().addServiceEventListener(TCFDSFRegisters.this, null);
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ getSession().removeServiceEventListener(this);
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor<IRegisterGroupDMData> rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof RegisterGroupDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ }
+ else {
+ rm.setData(new RegisterGroupData(((RegisterGroupDMC)dmc).context));
+ }
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void getRegisterData(IRegisterDMContext dmc, DataRequestMonitor<IRegisterDMData> rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof RegisterDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ }
+ else {
+ rm.setData(new RegisterData(((RegisterDMC)dmc).context));
+ }
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor<IBitFieldDMData> rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof BitFieldDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ }
+ else {
+ rm.setData(new BitFieldData(((BitFieldDMC)dmc).context));
+ }
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void getRegisterGroups(final IDMContext dmc, final DataRequestMonitor<IRegisterGroupDMContext[]> rm) {
+ if (rm.isCanceled()) return;
+ RegistersCache cache = null;
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc;
+ if (exe.registers_cache == null) exe.registers_cache =
+ new RegistersCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe });
+ cache = (RegistersCache)exe.registers_cache;
+ }
+ else if (dmc instanceof ObjectDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ cache = ((ObjectDMC)dmc).children;
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ if (cache != null) {
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getRegisterGroups(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ Map<String,ObjectDMC> c = cache.getData();
+ int cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof RegisterGroupDMC) cnt++;
+ }
+ if (cnt == 0 && c.size() > 0 && dmc instanceof TCFDSFExecutionDMC) {
+ // TODO DSF requires at least one group
+ RegisterGroupDMC[] arr = new RegisterGroupDMC[1];
+ arr[0] = new RegisterGroupDMC(getSession().getId(), cache.parents, cache.id, cache);
+ rm.setData(arr);
+ }
+ else {
+ RegisterGroupDMC[] arr = new RegisterGroupDMC[cnt];
+ cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof RegisterGroupDMC) arr[cnt++] = (RegisterGroupDMC)x;
+ }
+ rm.setData(arr);
+ }
+ }
+ rm.done();
+ }
+
+ public void getRegisterSubGroups(IDMContext dmc, DataRequestMonitor<IRegisterGroupDMContext[]> rm) {
+ getRegisterGroups(dmc, rm);
+ }
+
+ public void getRegisters(final IDMContext dmc, final DataRequestMonitor<IRegisterDMContext[]> rm) {
+ if (rm.isCanceled()) return;
+ RegistersCache cache = null;
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc;
+ if (exe.registers_cache == null) exe.registers_cache =
+ new RegistersCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe });
+ cache = (RegistersCache)exe.registers_cache;
+ }
+ else if (dmc instanceof ObjectDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ cache = ((ObjectDMC)dmc).children;
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ if (cache != null) {
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getRegisters(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ Map<String,ObjectDMC> c = cache.getData();
+ int cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof RegisterDMC) cnt++;
+ }
+ RegisterDMC[] arr = new RegisterDMC[cnt];
+ cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof RegisterDMC) arr[cnt++] = (RegisterDMC)x;
+ }
+ rm.setData(arr);
+ }
+ rm.done();
+ }
+
+ public void getBitFields(final IDMContext dmc, final DataRequestMonitor<IBitFieldDMContext[]> rm) {
+ if (rm.isCanceled()) return;
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof ObjectDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ RegistersCache cache = ((ObjectDMC)dmc).children;
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getBitFields(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ Map<String,ObjectDMC> c = cache.getData();
+ int cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof BitFieldDMC) cnt++;
+ }
+ BitFieldDMC[] arr = new BitFieldDMC[cnt];
+ cnt = 0;
+ for (IDMContext x : c.values()) {
+ if (x instanceof BitFieldDMC) arr[cnt++] = (BitFieldDMC)x;
+ }
+ rm.setData(arr);
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void writeBitField(IDMContext dmc, String val, String fmt, final RequestMonitor rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof ObjectDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ ((ObjectDMC)dmc).context.set(fmt, val, new org.eclipse.tm.tcf.services.IRegisters.DoneSet() {
+ public void doneSet(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ return;
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void writeBitField(IDMContext dmc, IMnemonic mnemonic, final RequestMonitor rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof ObjectDMC) {
+ if (((ObjectDMC)dmc).disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ NamedValue[] arr = ((ObjectDMC)dmc).context.getNamedValues();
+ if (arr != null) {
+ for (NamedValue nv : arr) {
+ if (nv.getName().equals(mnemonic.getShortName())) {
+ String fmt = org.eclipse.tm.tcf.services.IRegisters.FORMAT_DECIMAL;
+ String val = nv.getValue().toString();
+ ((ObjectDMC)dmc).context.set(fmt, val, new org.eclipse.tm.tcf.services.IRegisters.DoneSet() {
+ public void doneSet(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ return;
+ }
+ }
+ }
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown mnemonic", null)); //$NON-NLS-1$
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void writeRegister(IDMContext dmc, String val, String fmt, RequestMonitor rm) {
+ writeBitField(dmc, val, fmt, rm);
+ }
+
+ public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
+ if (tcf_reg_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$
+ }
+ else if (dmc instanceof ObjectDMC) {
+ rm.setData(((ObjectDMC)dmc).context.getAvailableFormats());
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public void getFormattedExpressionValue(final FormattedValueDMContext dmc,
+ final DataRequestMonitor<FormattedValueDMData> rm) {
+ if (rm.isCanceled()) return;
+ if (dmc instanceof ValueDMC) {
+ ValueDMC vmc = (ValueDMC)dmc;
+ if (vmc.disposed) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (!vmc.cache.validate()) {
+ vmc.cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getFormattedExpressionValue(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (vmc.cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", vmc.cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ rm.setData(vmc.cache.getData());
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+
+ public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String fmt) {
+ if (dmc instanceof ObjectDMC) {
+ ObjectDMC omc = (ObjectDMC)dmc;
+ ValueDMC res = omc.values.get(fmt);
+ if (res == null) {
+ omc.values.put(fmt, res = new ValueDMC(omc, fmt));
+ }
+ return res;
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+ if (dmc instanceof RegisterGroupDMC) {
+ getRegisterGroupData((RegisterGroupDMC)dmc, (DataRequestMonitor<IRegisterGroupDMData>)rm);
+ }
+ else if (dmc instanceof RegisterDMC) {
+ getRegisterData((RegisterDMC)dmc, (DataRequestMonitor<IRegisterDMData>)rm);
+ }
+ else if (dmc instanceof BitFieldDMC) {
+ getBitFieldData((BitFieldDMC)dmc, (DataRequestMonitor<IBitFieldDMData>)rm);
+ }
+ else if (dmc instanceof FormattedValueDMContext) {
+ getFormattedExpressionValue((FormattedValueDMContext)dmc, (DataRequestMonitor<FormattedValueDMData>)rm);
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent e) {
+ if (e.getReason() != StateChangeReason.STEP) {
+ RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache;
+ if (cache != null) cache.invalidateRegContents();
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent e) {
+ RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache;
+ if (cache != null) cache.invalidateRegContents();
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent e) {
+ RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getExecutionContext()).registers_cache;
+ if (cache != null) cache.dispose();
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java
new file mode 100644
index 000000000..0cbe78a87
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java
@@ -0,0 +1,1023 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.datamodel.ServiceDMContext;
+import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
+import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IRunControl.RunControlContext;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IRunControl {
+
+ public static class SuspendedEvent extends AbstractDMEvent<IExecutionDMContext> implements ISuspendedDMEvent {
+
+ private final StateChangeReason reason;
+
+ public SuspendedEvent(IExecutionDMContext dmc, String reason) {
+ super(dmc);
+ this.reason = toStateChangeReason(reason);
+ }
+
+ public StateChangeReason getReason() {
+ return reason;
+ }
+ }
+
+ public static class ResumedEvent extends AbstractDMEvent<IExecutionDMContext> implements IResumedDMEvent {
+
+ public ResumedEvent(IExecutionDMContext dmc) {
+ super(dmc);
+ }
+
+ public StateChangeReason getReason() {
+ return StateChangeReason.USER_REQUEST;
+ }
+ }
+
+ public class ContainerSuspendedEvent extends AbstractDMEvent<IExecutionDMContext> implements IContainerSuspendedDMEvent {
+
+ private final String trigger_id;
+ private final StateChangeReason reason;
+
+ public ContainerSuspendedEvent(IExecutionDMContext dmc, String trigger_id, String reason) {
+ super(dmc);
+ this.trigger_id = trigger_id;
+ this.reason = toStateChangeReason(reason);
+ }
+
+ public IExecutionDMContext getTriggeringContext() {
+ return cache.get(trigger_id);
+ }
+
+ public StateChangeReason getReason() {
+ return reason;
+ }
+ }
+
+ public static class ContainerResumedEvent extends AbstractDMEvent<IExecutionDMContext> implements IContainerResumedDMEvent {
+
+ public ContainerResumedEvent(IExecutionDMContext dmc) {
+ super(dmc);
+ }
+
+ public StateChangeReason getReason() {
+ return StateChangeReason.USER_REQUEST;
+ }
+ }
+
+ public static class StartedEvent extends AbstractDMEvent<IContainerDMContext> implements IStartedDMEvent {
+
+ private final IExecutionDMContext exe;
+
+ public StartedEvent(IContainerDMContext dmc, IExecutionDMContext exe) {
+ super(dmc);
+ this.exe = exe;
+ }
+
+ public IExecutionDMContext getExecutionContext() {
+ return exe;
+ }
+ }
+
+ public static class ChangedEvent extends AbstractDMEvent<IExecutionDMContext> {
+
+ public ChangedEvent(IExecutionDMContext dmc) {
+ super(dmc);
+ }
+ }
+
+ public static class ExitedEvent extends AbstractDMEvent<IContainerDMContext> implements IExitedDMEvent {
+
+ private final IExecutionDMContext exe;
+
+ public ExitedEvent(IContainerDMContext dmc, IExecutionDMContext exe) {
+ super(dmc);
+ this.exe = exe;
+ }
+
+ public IExecutionDMContext getExecutionContext() {
+ return exe;
+ }
+ }
+
+ private final org.eclipse.tm.tcf.services.IRunControl.RunControlListener run_listener =
+ new org.eclipse.tm.tcf.services.IRunControl.RunControlListener() {
+
+ public void containerResumed(String[] context_ids) {
+ for (String id : context_ids) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContextResumed();
+ }
+ for (String id : context_ids) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null && n.context.isValid()) {
+ RunControlContext c = n.context.getData();
+ if (c.isContainer()) {
+ getSession().dispatchEvent(new ContainerResumedEvent(n), getProperties());
+ }
+ }
+ }
+ }
+
+ public void containerSuspended(String trigger_id, String pc,
+ String reason, Map<String, Object> params,
+ String[] suspended_ids) {
+ if (trigger_id != null) {
+ ExecutionDMC n = cache.get(trigger_id);
+ if (n != null) n.onContextSuspended(pc, reason, params);
+ }
+ for (String id : suspended_ids) {
+ if (id.equals(trigger_id)) continue;
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContainerSuspended(reason);
+ }
+ for (String id : suspended_ids) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null && n.context.isValid()) {
+ RunControlContext c = n.context.getData();
+ if (c.isContainer()) {
+ getSession().dispatchEvent(new ContainerSuspendedEvent(n, trigger_id, reason), getProperties());
+ }
+ }
+ }
+ }
+
+ public void contextAdded(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ ExecutionDMC n = cache.get(ctx.getParentID());
+ if (n != null) n.onContextAdded(ctx);
+ }
+ }
+
+ public void contextChanged(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ ExecutionDMC n = cache.get(ctx.getID());
+ if (n != null) n.onContextChanged(ctx);
+ }
+ }
+
+ public void contextException(String id, String msg) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContextException(msg);
+ }
+
+ public void contextRemoved(String[] context_ids) {
+ for (String id : context_ids) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContextRemoved();
+ }
+ }
+
+ public void contextResumed(String id) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContextResumed();
+ }
+
+ public void contextSuspended(String id, String pc, String reason, Map<String, Object> params) {
+ ExecutionDMC n = cache.get(id);
+ if (n != null) n.onContextSuspended(pc, reason, params);
+ }
+ };
+
+ private static class ExecutionState {
+ boolean is_suspended;
+ boolean is_running;
+ String suspend_pc;
+ String suspend_reason;
+ Map<String,Object> suspend_params;
+ }
+
+ private class ExecutionDMC extends TCFDSFExecutionDMC {
+
+ final String id;
+ final ExecutionDMC parent;
+ final IMemoryBlockRetrievalExtension mem_retrieval;
+
+ boolean disposed;
+ int is_stepping;
+ int is_resuming;
+
+ final TCFDataCache<RunControlContext> context;
+ final TCFDataCache<Map<String,ExecutionDMC>> children;
+ final TCFDataCache<ExecutionState> state;
+
+ public ExecutionDMC(ExecutionDMC parent, final String id) {
+ super(TCFDSFRunControl.this, parent == null ?
+ new IDMContext[0] : new IDMContext[] { parent });
+ this.parent = parent;
+ this.id = id;
+ DsfMemoryBlockRetrieval mr = null;
+ try {
+ mr = new DsfMemoryBlockRetrieval(ITCFConstants.ID_TCF_DEBUG_MODEL, this);
+ }
+ catch (DebugException e) {
+ e.printStackTrace();
+ };
+ mem_retrieval = mr;
+ context = new TCFDataCache<RunControlContext>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ if (id == null || tcf_run_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_run_service.getContext(id, new IRunControl.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception err, IRunControl.RunControlContext ctx) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ error = err;
+ }
+ else {
+ data = ctx;
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ children = new TCFDataCache<Map<String,ExecutionDMC>>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ if (tcf_run_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_run_service.getChildren(id, new IRunControl.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception err, String[] contexts) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ if (data == null) data = new HashMap<String,ExecutionDMC>();
+ data.clear();
+ for (int i = 0; i < contexts.length; i++) {
+ String id = contexts[i];
+ ExecutionDMC n = cache.get(id);
+ if (n == null) {
+ n = new ExecutionDMC(ExecutionDMC.this, id);
+ cache.put(n.id, n);
+ }
+ data.put(id, n);
+ }
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ state = new TCFDataCache<ExecutionState>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ assert context.isValid();
+ RunControlContext c = context.getData();
+ if (c == null || !c.hasState()) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = c.getState(new IRunControl.DoneGetState() {
+ public void doneGetState(IToken token, Exception err, boolean suspend, String pc, String reason, Map<String,Object> params) {
+ if (token != command) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ data = new ExecutionState();
+ data.is_running = !suspend;
+ data.is_suspended = suspend;
+ if (suspend) {
+ data.suspend_pc = pc;
+ data.suspend_reason = reason;
+ data.suspend_params = params;
+ }
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ }
+
+ @Override
+ public String toString() {
+ return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!super.baseEquals(obj)) return false;
+ String obj_id = ((ExecutionDMC)obj).id;
+ if (obj_id == null) return id == null;
+ return obj_id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ if (id == null) return 0;
+ return id.hashCode();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object getAdapter(Class cls) {
+ Object obj = null;
+ if (cls == IMemoryBlockRetrieval.class) obj = mem_retrieval;
+ if (cls == IMemoryBlockRetrievalExtension.class) obj = mem_retrieval;
+ if (obj == null) obj = super.getAdapter(cls);
+ return obj;
+ }
+
+ @Override
+ public String getTcfContextId() {
+ return id;
+ }
+
+ @Override
+ public void addStateWaitingRequest(IDataRequest req) {
+ state.addWaitingRequest(req);
+ }
+
+ @Override
+ public TCFAddress getPC() {
+ ExecutionState st = state.getData();
+ if (st == null) return null;
+ if (st.suspend_pc == null) return null;
+ return new TCFAddress(new BigInteger(st.suspend_pc));
+ }
+
+ @Override
+ public boolean validateState() {
+ return state.validate();
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return disposed;
+ }
+
+ void dispose() {
+ assert !disposed;
+ context.cancel();
+ children.cancel();
+ state.cancel();
+ if (children.isValid()) {
+ Map<String,ExecutionDMC> m = children.getData();
+ if (m != null) {
+ for (ExecutionDMC n : m.values()) n.dispose();
+ }
+ }
+ cache.remove(id);
+ disposed = true;
+ }
+
+ /*--------------------------------------------------------------------------------------*/
+ /* Events */
+
+ void onContextAdded(IRunControl.RunControlContext c) {
+ String id = c.getID();
+ assert !disposed;
+ assert cache.get(id) == null;
+ ExecutionDMC n = new ExecutionDMC(this, id);
+ n.context.reset(c);
+ if (children.isValid()) {
+ Map<String,ExecutionDMC> m = children.getData();
+ if (m != null) m.put(id, n);
+ }
+ cache.put(id, n);
+ getSession().dispatchEvent(new StartedEvent(this, n), getProperties());
+ }
+
+ void onContextChanged(IRunControl.RunControlContext c) {
+ assert !disposed;
+ context.reset(c);
+ getSession().dispatchEvent(new ChangedEvent(this), getProperties());
+ }
+
+ void onContextRemoved() {
+ assert !disposed;
+ if (parent != null && parent.children.isValid()) {
+ Map<String,ExecutionDMC> m = parent.children.getData();
+ if (m != null) m.remove(id);
+ }
+ dispose();
+ getSession().dispatchEvent(new ExitedEvent(parent, this), getProperties());
+ }
+
+ void onContainerSuspended(String reason) {
+ assert !disposed;
+ if (!context.isValid()) return;
+ RunControlContext rc = context.getData();
+ if (rc == null) return;
+ if (!rc.hasState()) return;
+ state.reset();
+ getSession().dispatchEvent(new SuspendedEvent(this, reason), getProperties());
+ }
+
+ void onContextSuspended(String pc, String reason, Map<String,Object> params) {
+ assert !disposed;
+ assert !context.isValid() || context.getData().hasState();
+ ExecutionState st = new ExecutionState();
+ st.is_suspended = true;
+ st.suspend_pc = pc;
+ st.suspend_reason = reason;
+ st.suspend_params = params;
+ state.reset(st);
+ getSession().dispatchEvent(new SuspendedEvent(this, reason), getProperties());
+ }
+
+ void onContextResumed() {
+ assert !disposed;
+ assert !context.isValid() || context.getData().hasState();
+ ExecutionState st = new ExecutionState();
+ st.is_running = true;
+ state.reset(st);
+ getSession().dispatchEvent(new ResumedEvent(this), getProperties());
+ }
+
+ void onContextException(String msg) {
+ assert !disposed;
+ // TODO onContextException handling
+ }
+ }
+
+ private static class ExecutionData implements IExecutionDMData {
+
+ private final StateChangeReason reason;
+
+ ExecutionData(StateChangeReason reason) {
+ this.reason = reason;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public StateChangeReason getStateChangeReason() {
+ return reason;
+ }
+ }
+
+ private static StateChangeReason toStateChangeReason(String s) {
+ if (s == null) return StateChangeReason.UNKNOWN;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_USER_REQUEST)) return StateChangeReason.USER_REQUEST;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_STEP)) return StateChangeReason.STEP;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_BREAKPOINT)) return StateChangeReason.BREAKPOINT;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_EXCEPTION)) return StateChangeReason.EXCEPTION;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_CONTAINER)) return StateChangeReason.CONTAINER;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_WATCHPOINT)) return StateChangeReason.WATCHPOINT;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_SIGNAL)) return StateChangeReason.SIGNAL;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_SHAREDLIB)) return StateChangeReason.SHAREDLIB;
+ if (s.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_ERROR)) return StateChangeReason.ERROR;
+ return StateChangeReason.UNKNOWN;
+ }
+
+ private final IChannel channel;
+ private final org.eclipse.tm.tcf.services.IRunControl tcf_run_service;
+ private final Map<String,ExecutionDMC> cache = new HashMap<String,ExecutionDMC>();
+ private final ExecutionDMC root_dmc;
+ private IDMContext service_dmc;
+
+ public TCFDSFRunControl(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ this.channel = channel;
+ tcf_run_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IRunControl.class);
+ if (tcf_run_service != null) tcf_run_service.addListener(run_listener);
+ service_dmc = new ServiceDMContext(this, "#run_control");
+ root_dmc = new ExecutionDMC(null, null);
+ cache.put(null, root_dmc);
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ org.eclipse.dd.dsf.debug.service.IRunControl.class.getName(),
+ TCFDSFRunControl.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ if (tcf_run_service != null) tcf_run_service.removeListener(run_listener);
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void getModelData(IDMContext dmc, final DataRequestMonitor<?> rm) {
+ if (dmc instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)dmc;
+ if (!ctx.context.validate()) {
+ ctx.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getModelData(ctx, rm);
+ }
+ });
+ return;
+ }
+ if (ctx.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", ctx.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (ctx.context.getData() == null) {
+ ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN);
+ ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt);
+ rm.done();
+ return;
+ }
+ if (!ctx.context.getData().hasState()) {
+ ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN);
+ ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt);
+ rm.done();
+ return;
+ }
+ if (!ctx.state.validate()) {
+ ctx.state.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getModelData(ctx, rm);
+ }
+ });
+ return;
+ }
+ if (ctx.state.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", ctx.state.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (ctx.state.getData() == null) {
+ ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN);
+ ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt);
+ rm.done();
+ return;
+ }
+ ExecutionData dt = new ExecutionData(toStateChangeReason(ctx.state.getData().suspend_reason));
+ ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt);
+ rm.done();
+ }
+ else if (dmc == service_dmc) {
+ ((DataRequestMonitor<TCFDSFRunControl>)rm).setData(this);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public IDMContext getServiceContext() {
+ return service_dmc;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public boolean canInstructionStep(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ return c != null && c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO);
+ }
+ }
+ return false;
+ }
+
+ public boolean canResume(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ return c != null && c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME);
+ }
+ }
+ return false;
+ }
+
+ public boolean canStep(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null) {
+ if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE)) return true;
+ if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO)) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean canSuspend(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ return c != null && c.canSuspend();
+ }
+ }
+ return false;
+ }
+
+ public TCFDSFExecutionDMC getContext(String id) {
+ return cache.get(id);
+ }
+
+ public void getContainerContexts(IContainerDMContext context, final DataRequestMonitor<IExecutionDMContext[]> rm) {
+ getContexts(context, rm, false);
+ }
+
+ public void getExecutionContexts(IContainerDMContext context, final DataRequestMonitor<IExecutionDMContext[]> rm) {
+ getContexts(context, rm, true);
+ }
+
+ public void getContexts(IContainerDMContext context,
+ final DataRequestMonitor<IExecutionDMContext[]> rm, final boolean has_state) {
+ if (context == null) context = root_dmc;
+ if (context instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)context;
+ TCFDataCache<Map<String,ExecutionDMC>> cache = ctx.children;
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getContexts(ctx, rm, has_state);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (cache.getData() == null) {
+ rm.setData(new ExecutionDMC[0]);
+ rm.done();
+ return;
+ }
+ final Set<IDataRequest> reqs = new HashSet<IDataRequest>();
+ for (ExecutionDMC e : cache.getData().values()) {
+ if (!e.context.validate()) {
+ IDataRequest req = new IDataRequest() {
+ public void cancel() {
+ if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state);
+ }
+ public void done() {
+ if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state);
+ }
+ };
+ reqs.add(req);
+ e.context.addWaitingRequest(req);
+ }
+ // TODO DSF service design does not support lazy retrieval of context state (because isSuspened() is not async)
+ else if (!e.state.validate()) {
+ IDataRequest req = new IDataRequest() {
+ public void cancel() {
+ if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state);
+ }
+ public void done() {
+ if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state);
+ }
+ };
+ reqs.add(req);
+ e.state.addWaitingRequest(req);
+ }
+ }
+ if (reqs.isEmpty()) {
+ ArrayList<ExecutionDMC> l = new ArrayList<ExecutionDMC>();
+ for (ExecutionDMC e : cache.getData().values()) {
+ assert e.context.isValid();
+ RunControlContext c = e.context.getData();
+ if (c.hasState() == has_state) l.add(e);
+ }
+ rm.setData(l.toArray(new ExecutionDMC[l.size()]));
+ rm.done();
+ }
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public Collection<TCFDSFExecutionDMC> getCachedContexts() {
+ ArrayList<TCFDSFExecutionDMC> l = new ArrayList<TCFDSFExecutionDMC>();
+ for (ExecutionDMC dmc : cache.values()) l.add(dmc);
+ return l;
+ }
+
+ public void step(IDMContext context, StepType stepType, final RequestMonitor rm) {
+ if (context instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null) {
+ int md = -1;
+ if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE)) {
+ switch (stepType) {
+ case STEP_OVER:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER_LINE;
+ break;
+ case STEP_INTO:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE;
+ break;
+ case STEP_RETURN:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT;
+ break;
+ }
+ }
+ else {
+ switch (stepType) {
+ case STEP_OVER:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER;
+ break;
+ case STEP_INTO:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO;
+ break;
+ case STEP_RETURN:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT;
+ break;
+ }
+ }
+ if (md < 0) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ NOT_SUPPORTED, "Invalid step type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ c.resume(md, 1, new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ ctx.is_stepping--;
+ rm.done();
+ }
+ });
+ ctx.is_stepping++;
+ }
+ return;
+ }
+ }
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void instructionStep(IDMContext context, StepType stepType, final RequestMonitor rm) {
+ if (context instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null) {
+ int md = -1;
+ switch (stepType) {
+ case STEP_OVER:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER;
+ break;
+ case STEP_INTO:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO;
+ break;
+ case STEP_RETURN:
+ md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT;
+ break;
+ }
+ if (md < 0) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ NOT_SUPPORTED, "Invalid step type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ c.resume(md, 1, new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ ctx.is_stepping--;
+ rm.done();
+ }
+ });
+ ctx.is_stepping++;
+ }
+ return;
+ }
+ }
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public boolean isStepping(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC x = (ExecutionDMC)context;
+ return x.is_stepping > 0;
+ }
+ return false;
+ }
+
+ public void resume(IDMContext context, final RequestMonitor rm) {
+ if (context instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null) {
+ c.resume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME, 1,
+ new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ ctx.is_resuming--;
+ rm.done();
+ }
+ });
+ ctx.is_resuming++;
+ return;
+ }
+ }
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void suspend(IDMContext context, final RequestMonitor rm) {
+ if (context instanceof ExecutionDMC) {
+ final ExecutionDMC ctx = (ExecutionDMC)context;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null) {
+ c.suspend(new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ return;
+ }
+ }
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public boolean isSuspended(IDMContext context) {
+ if (context instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)context;
+ boolean r = false;
+ if (ctx.context.isValid()) {
+ RunControlContext c = ctx.context.getData();
+ if (c != null && c.hasState()) {
+ if (ctx.is_resuming == 0 && ctx.is_stepping == 0 && ctx.state.isValid()) {
+ ExecutionState st = ctx.state.getData();
+ if (st != null) r = st.is_suspended;
+ }
+ }
+ else if (ctx.children.isValid()) {
+ Map<String,ExecutionDMC> m = ctx.children.getData();
+ if (m != null) {
+ for (ExecutionDMC e : m.values()) {
+ if (isSuspended(e)) r = true;
+ }
+ }
+ }
+ }
+ return r;
+ }
+ return false;
+ }
+
+ public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) {
+ if (dmc instanceof ExecutionDMC) {
+ ExecutionDMC ctx = (ExecutionDMC)dmc;
+ StateChangeReason r = StateChangeReason.UNKNOWN;
+ if (ctx.state.isValid()) {
+ ExecutionState st = ctx.state.getData();
+ if (st != null && st.suspend_reason != null) {
+ r = toStateChangeReason(st.suspend_reason);
+ }
+ }
+ rm.setData(new ExecutionData(r));
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Given context: " + dmc + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ rm.done();
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java
new file mode 100644
index 000000000..67f7c9461
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java
@@ -0,0 +1,516 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.cdt.core.IAddress;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.datamodel.ServiceDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl;
+import org.eclipse.dd.dsf.debug.service.IStack;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.ILineNumbers;
+import org.eclipse.tm.tcf.services.IStackTrace;
+import org.eclipse.tm.tcf.services.ILineNumbers.CodeArea;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFStack extends AbstractDsfService implements IStack {
+
+ private static final String TOP_FRAME = "TopFrame:";
+
+ private class TCFFrameDMC extends AbstractDMContext implements IFrameDMContext, Comparable<TCFFrameDMC> {
+
+ final String id;
+ final TCFDSFExecutionDMC exe_dmc;
+ final TCFDataCache<TCFFrameData> frame_data;
+
+ int level;
+ TCFFrameData prev_data;
+
+ public TCFFrameDMC(final TCFDSFExecutionDMC exe_dmc, final String id) {
+ super(TCFDSFStack.this.getSession().getId(), new IDMContext[] { exe_dmc });
+ this.id = id;
+ this.exe_dmc = exe_dmc;
+ frame_data = new TCFDataCache<TCFFrameData>(channel) {
+
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ if (id == null || tcf_stk_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ if (level == 0) {
+ assert id.startsWith(TOP_FRAME);
+ // Top frame is special case: most of its data is stored in CPU registers.
+ // Other frames are stored in memory - in thread stack area.
+ return getTopFrame();
+ }
+ command = tcf_stk_service.getContext(new String[]{ id }, new IStackTrace.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception err, IStackTrace.StackTraceContext[] context) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ error = err;
+ data = null;
+ }
+ else {
+ TCFAddress a = null;
+ Number n = context[0].getReturnAddress();
+ if (n != null) a = new TCFAddress(n);
+ // Optimization: skip source position lookup if same address
+ if (prev_data != null && prev_data.address.equals(a)) {
+ data = prev_data;
+ data.context = context[0];
+ data.level = level;
+ }
+ else {
+ data = new TCFFrameData();
+ data.context = context[0];
+ data.address = a;
+ data.level = level;
+ if (!getSourcePos()) return;
+ }
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+
+ private boolean getTopFrame() {
+ assert level == 0;
+ if (!exe_dmc.validateState()) {
+ exe_dmc.addStateWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ reset();
+ }
+ public void done() {
+ validate();
+ }
+ });
+ return false;
+ }
+ prev_data = data = new TCFFrameData();
+ data.address = exe_dmc.getPC();
+ data.level = level;
+ if (!getSourcePos()) return false;
+ valid = true;
+ return true;
+ }
+
+ private boolean getSourcePos() {
+ if (tcf_lns_service == null) return true;
+ if (data.address == null) return true;
+ BigInteger a1 = data.address.getValue();
+ BigInteger a2 = data.address.add(1).getValue();
+ command = tcf_lns_service.mapToSource(exe_dmc.getTcfContextId(), a1, a2, new ILineNumbers.DoneMapToSource() {
+
+ public void doneMapToSource(IToken token, Exception err, CodeArea[] areas) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data.src_pos_error = err;
+ }
+ else if (areas != null && areas.length > 0) {
+ for (ILineNumbers.CodeArea area : areas) {
+ if (data.code_area == null || area.start_line < data.code_area.start_line) {
+ data.code_area = area;
+ }
+ }
+ prev_data = data;
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return super.baseEquals(other) && ((TCFFrameDMC)other).id.equals(id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return baseToString() + ".frame[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ public int compareTo(TCFFrameDMC f) {
+ if (level < f.level) return -1;
+ if (level > f.level) return +1;
+ return 0;
+ }
+ }
+
+ private static class TCFFrameData implements IFrameDMData {
+
+ IStackTrace.StackTraceContext context;
+ IAddress address;
+ int level;
+ String function;
+ Throwable src_pos_error;
+ ILineNumbers.CodeArea code_area;
+
+ public IAddress getAddress() {
+ return address;
+ }
+
+ public String getFunction() {
+ return function;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public String getFile() {
+ if (code_area == null) return null;
+ return code_area.file;
+ }
+
+ public int getLine() {
+ if (code_area == null) return -1;
+ return code_area.start_line + 1;
+ }
+
+ public int getColumn() {
+ if (code_area == null) return -1;
+ return code_area.start_column + 1;
+ }
+ }
+
+ private class FramesCache extends TCFDataCache<Map<String,TCFFrameDMC>> implements TCFDSFExecutionDMC.DataCache {
+
+ private final TCFDSFExecutionDMC dmc;
+ private final Map<String,TCFFrameDMC> frame_pool;
+
+ FramesCache(IChannel channel, TCFDSFExecutionDMC dmc) {
+ super(channel);
+ this.dmc = dmc;
+ frame_pool = new HashMap<String,TCFFrameDMC>();
+ }
+
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ if (tcf_stk_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ assert !dmc.isDisposed();
+ command = tcf_stk_service.getChildren(dmc.getTcfContextId(), new IStackTrace.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception err, String[] contexts) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ data = null;
+ error = err;
+ }
+ else {
+ data = new HashMap<String,TCFFrameDMC>();
+ for (int i = 0; i < contexts.length; i++) {
+ String id = contexts[i];
+ TCFFrameDMC n = frame_pool.get(id);
+ if (n == null) frame_pool.put(id, n = new TCFFrameDMC(dmc, id));
+ n.level = contexts.length - i;
+ data.put(id, n);
+ }
+ String id = TOP_FRAME + dmc.getTcfContextId();
+ TCFFrameDMC n = frame_pool.get(id);
+ if (n == null) frame_pool.put(id, n = new TCFFrameDMC(dmc, id));
+ n.level = 0;
+ data.put(id, n);
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+
+ void invalidateFrames() {
+ reset();
+ for (TCFFrameDMC dmc : frame_pool.values()) dmc.frame_data.reset();
+ }
+
+ void dispose() {
+ }
+ }
+
+ private final IChannel channel;
+ private final IStackTrace tcf_stk_service;
+ private final ILineNumbers tcf_lns_service;
+ private IDMContext service_dmc;
+
+ public TCFDSFStack(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ this.channel = channel;
+ tcf_stk_service = channel.getRemoteService(IStackTrace.class);
+ tcf_lns_service = channel.getRemoteService(ILineNumbers.class);
+ service_dmc = new ServiceDMContext(this, "#stack_trace");
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ IStack.class.getName(),
+ TCFDSFStack.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ getSession().addServiceEventListener(TCFDSFStack.this, null);
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ getSession().removeServiceEventListener(this);
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public IDMContext getServiceContext() {
+ return service_dmc;
+ }
+
+ public void getArguments(IDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) {
+ if (dmc instanceof TCFFrameDMC) {
+ // TODO function arguments
+ rm.setData(new IVariableDMContext[0]);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getFrameData(final IFrameDMContext dmc, final DataRequestMonitor<IFrameDMData> rm) {
+ if (dmc instanceof TCFFrameDMC) {
+ final TCFFrameDMC frame_dmc = (TCFFrameDMC)dmc;
+ TCFDataCache<TCFFrameData> cache = frame_dmc.frame_data;
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getFrameData(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ rm.setData(cache.getData());
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getFrames(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext[]> rm) {
+ if (tcf_stk_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Stack trace service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc;
+ if (exe.isDisposed()) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe);
+ FramesCache cache = (FramesCache)exe.stack_frames_cache;
+ if (!cache.validate()) {
+ cache.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getFrames(dmc, rm);
+ }
+ });
+ return;
+ }
+ if (cache.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ Map<String,TCFFrameDMC> c = cache.getData();
+ TCFFrameDMC[] arr = c.values().toArray(new TCFFrameDMC[c.size()]);
+ Arrays.sort(arr);
+ rm.setData(arr);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getLocals(IDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) {
+ if (dmc instanceof TCFFrameDMC) {
+ // TODO function local variables
+ rm.setData(new IVariableDMContext[0]);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getStackDepth(DataRequestMonitor<Integer> rm) {
+ // TODO don't know what getStackDepth() is supposed to return
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+
+ public void getStackDepth(int maxDepth, DataRequestMonitor<Integer> rm) {
+ // TODO don't know what getStackDepth() is supposed to return
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+
+ public void getTopFrame(IDMContext dmc, DataRequestMonitor<IFrameDMContext> rm) {
+ if (dmc instanceof TCFDSFExecutionDMC) {
+ TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc;
+ if (exe.isDisposed()) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe);
+ FramesCache cache = (FramesCache)exe.stack_frames_cache;
+ String id = TOP_FRAME + exe.getTcfContextId();
+ TCFFrameDMC n = cache.frame_pool.get(id);
+ if (n == null) cache.frame_pool.put(id, n = new TCFFrameDMC(exe, id));
+ n.level = 0;
+ rm.setData(n);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor<IVariableDMData> rm) {
+ // TODO model data for local variables
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+
+ public boolean isStackAvailable(IDMContext dmc) {
+ return tcf_stk_service != null && dmc instanceof TCFDSFExecutionDMC;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+ if (dmc instanceof IFrameDMContext) {
+ getFrameData((IFrameDMContext)dmc, (DataRequestMonitor<IFrameDMData>)rm);
+ }
+ else if (dmc == service_dmc) {
+ ((DataRequestMonitor<TCFDSFStack>)rm).setData(this);
+ rm.done();
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IRunControl.IResumedDMEvent e) {
+ if (e.getReason() != StateChangeReason.STEP) {
+ FramesCache cache = (FramesCache)((TCFDSFExecutionDMC)e.getDMContext()).stack_frames_cache;
+ if (cache != null) cache.invalidateFrames();
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
+ FramesCache cache = (FramesCache)((TCFDSFExecutionDMC)e.getDMContext()).stack_frames_cache;
+ if (cache != null) cache.invalidateFrames();
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IRunControl.IExitedDMEvent e) {
+ FramesCache cache = (FramesCache)((TCFDSFExecutionDMC)e.getExecutionContext()).stack_frames_cache;
+ if (cache != null) cache.dispose();
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java
new file mode 100644
index 000000000..dd5e2042b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.DMContexts;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl;
+import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
+import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFStepQueueManager extends AbstractDsfService
+implements IStepQueueManager{
+
+ private static class StepRequest {
+ StepType fStepType;
+ boolean fIsInstructionStep;
+ StepRequest(StepType type, boolean instruction) {
+ fStepType = type;
+ fIsInstructionStep = instruction;
+ }
+ }
+
+ private IRunControl fRunControl;
+ private int fQueueDepth = 3;
+ private Map<IExecutionDMContext,List<StepRequest>> fStepQueues = new HashMap<IExecutionDMContext,List<StepRequest>>();
+ private Map<IExecutionDMContext,Boolean> fTimedOutFlags = new HashMap<IExecutionDMContext,Boolean>();
+ private Map<IExecutionDMContext,ScheduledFuture<?>> fTimedOutFutures = new HashMap<IExecutionDMContext,ScheduledFuture<?>>();
+
+ public TCFDSFStepQueueManager(DsfSession session) {
+ super(session);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // IDsfService
+ @Override
+ public void initialize(final RequestMonitor requestMonitor) {
+ super.initialize(
+ new RequestMonitor(getExecutor(), requestMonitor) {
+ @Override
+ protected void handleOK() {
+ doInitialize(requestMonitor);
+ }});
+ }
+
+ private void doInitialize(final RequestMonitor requestMonitor) {
+ fRunControl = getServicesTracker().getService(IRunControl.class);
+
+ getSession().addServiceEventListener(this, null);
+ register(new String[]{IStepQueueManager.class.getName()}, new Hashtable<String,String>());
+ requestMonitor.done();
+ }
+
+ @Override
+ public void shutdown(final RequestMonitor requestMonitor) {
+ unregister();
+ getSession().removeServiceEventListener(this);
+ super.shutdown(requestMonitor);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // AbstractService
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // IStepQueueManager
+ public boolean canEnqueueStep(IDMContext ctx) {
+ IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
+ return execCtx != null &&
+ ( (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx)) ||
+ (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)) );
+ }
+
+ // IStepQueueManager
+ public boolean canEnqueueInstructionStep(IDMContext ctx) {
+ IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
+ return execCtx != null &&
+ ( (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx)) ||
+ (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)) );
+ }
+
+ public int getPendingStepCount(IDMContext execCtx) {
+ List<StepRequest> stepQueue = fStepQueues.get(execCtx);
+ if (stepQueue == null) return 0;
+ return stepQueue.size();
+ }
+
+ public void enqueueStep(IDMContext ctx, StepType stepType) {
+ IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
+ if (execCtx != null) {
+ if (fRunControl.canStep(execCtx)) {
+ fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null));
+ } else if (canEnqueueStep(execCtx)) {
+ List<StepRequest> stepQueue = fStepQueues.get(execCtx);
+ if (stepQueue == null) {
+ stepQueue = new LinkedList<StepRequest>();
+ fStepQueues.put(execCtx, stepQueue);
+ }
+ if (stepQueue.size() < fQueueDepth) {
+ stepQueue.add(new StepRequest(stepType, false));
+ }
+ }
+ }
+ }
+
+ public void enqueueInstructionStep(IDMContext ctx, StepType stepType) {
+ IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
+ if (execCtx != null) {
+ if (fRunControl.canInstructionStep(execCtx)) {
+ fRunControl.instructionStep(execCtx, stepType, new RequestMonitor(getExecutor(), null));
+ }
+ else if (canEnqueueInstructionStep(execCtx)) {
+ List<StepRequest> stepQueue = fStepQueues.get(execCtx);
+ if (stepQueue == null) {
+ stepQueue = new LinkedList<StepRequest>();
+ fStepQueues.put(execCtx, stepQueue);
+ }
+ if (stepQueue.size() < fQueueDepth) {
+ stepQueue.add(new StepRequest(stepType, true));
+ }
+ }
+ }
+ }
+
+ public boolean isSteppingTimedOut(IDMContext context) {
+ IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
+ if (execCtx != null) {
+ return fTimedOutFlags.containsKey(execCtx) ? fTimedOutFlags.get(execCtx) : false;
+ }
+ return false;
+ }
+
+
+ public int getStepQueueDepth() { return fQueueDepth; }
+ public void setStepQueueDepth(int depth) { fQueueDepth = depth; }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ @DsfServiceEventHandler
+ public void eventDispatched(ISuspendedDMEvent e) {
+ // Take care of the stepping time out
+ fTimedOutFlags.remove(e.getDMContext());
+ ScheduledFuture<?> future = fTimedOutFutures.remove(e.getDMContext());
+ if (future != null) future.cancel(false);
+
+ // Check if there's a step pending, if so execute it
+ if (fStepQueues.containsKey(e.getDMContext())) {
+ List<StepRequest> queue = fStepQueues.get(e.getDMContext());
+ StepRequest request = queue.remove(queue.size() - 1);
+ if (queue.isEmpty()) fStepQueues.remove(e.getDMContext());
+ if (request.fIsInstructionStep) {
+ if (fRunControl.canInstructionStep(e.getDMContext())) {
+ fRunControl.instructionStep(
+ e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null));
+ } else {
+ // For whatever reason we can't step anymore, so clear out
+ // the step queue.
+ fStepQueues.remove(e.getDMContext());
+ }
+ } else {
+ if (fRunControl.canStep(e.getDMContext())) {
+ fRunControl.step(e.getDMContext(), request.fStepType,new RequestMonitor(getExecutor(), null));
+ } else {
+ // For whatever reason we can't step anymore, so clear out
+ // the step queue.
+ fStepQueues.remove(e.getDMContext());
+ }
+ }
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(final IResumedDMEvent e) {
+ if (e.getReason().equals(StateChangeReason.STEP)) {
+ fTimedOutFlags.put(e.getDMContext(), Boolean.FALSE);
+ // We shouldn't have a stepping timeout running unless we get two
+ // stepping events in a row without a suspended, which would be a
+ // protocol error.
+ assert !fTimedOutFutures.containsKey(e.getDMContext());
+ fTimedOutFutures.put(
+ e.getDMContext(),
+ getExecutor().schedule(
+ new DsfRunnable() { public void run() {
+ fTimedOutFutures.remove(e.getDMContext());
+
+ // Issue the stepping time-out event.
+ getSession().dispatchEvent(
+ new ISteppingTimedOutEvent() {
+ public IExecutionDMContext getDMContext() { return e.getDMContext(); }
+ },
+ getProperties());
+ }},
+ STEPPING_TIMEOUT, TimeUnit.MILLISECONDS)
+ );
+
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(ISteppingTimedOutEvent e) {
+ fTimedOutFlags.put(e.getDMContext(), Boolean.TRUE);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java
new file mode 100644
index 000000000..eaf308a9b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.INativeProcesses.IThreadDMContext;
+import org.eclipse.dd.dsf.service.IDsfService;
+
+public abstract class TCFDSFThreadDMC extends AbstractDMContext implements IThreadDMContext {
+
+ public TCFDSFThreadDMC(IDsfService service, IDMContext[] parents) {
+ super(service, parents);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java
new file mode 100644
index 000000000..e95bb43d4
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.dsf.services;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+
+public abstract class TCFDataCache<V> {
+
+ protected Throwable error;
+ protected IToken command;
+ protected boolean valid;
+ protected V data;
+
+ protected final IChannel channel;
+ protected final Collection<IDataRequest> waiting_list = new ArrayList<IDataRequest>();
+
+ public TCFDataCache(IChannel channel) {
+ assert channel != null;
+ this.channel = channel;
+ }
+
+ public void cancel() {
+ // Cancel current data retrieval command
+ if (command != null) {
+ command.cancel();
+ command = null;
+ }
+ // Cancel waiting data requests
+ if (!waiting_list.isEmpty()) {
+ IDataRequest[] arr = waiting_list.toArray(new IDataRequest[waiting_list.size()]);
+ waiting_list.clear();
+ for (IDataRequest r : arr) r.cancel();
+ }
+ }
+
+ public boolean validate() {
+ assert Protocol.isDispatchThread();
+ if (channel.getState() != IChannel.STATE_OPEN) {
+ error = null;
+ command = null;
+ data = null;
+ valid = true;
+ return true;
+ }
+ if (command != null) {
+ return false;
+ }
+ if (!valid && !startDataRetrieval()) return false;
+ assert command == null;
+ if (!waiting_list.isEmpty()) {
+ IDataRequest[] arr = waiting_list.toArray(new IDataRequest[waiting_list.size()]);
+ waiting_list.clear();
+ for (IDataRequest r : arr) r.done();
+ }
+ return true;
+ }
+
+ public void addWaitingRequest(IDataRequest req) {
+ assert !valid;
+ waiting_list.add(req);
+ }
+
+ public void reset(V data) {
+ cancel();
+ this.data = data;
+ error = null;
+ valid = true;
+ }
+
+ public void reset() {
+ cancel();
+ error = null;
+ data = null;
+ valid = false;
+ }
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public Throwable getError() {
+ assert valid;
+ return error;
+ }
+
+ public V getData() {
+ assert valid;
+ return data;
+ }
+
+ public abstract boolean startDataRetrieval();
+}

Back to the top