Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraleherbau2011-05-25 12:35:21 +0000
committeraleherbau2011-05-25 12:35:21 +0000
commit4e0d17e91c267c23b23e46ea09b804c6869a09c6 (patch)
tree9c7dfd9fd84abbf32699226e42013701f62d57c7 /python/src/tcf
parent5fa9053b2ee4244f0ccc2dcad4273e69ff371068 (diff)
downloadorg.eclipse.tcf-4e0d17e91c267c23b23e46ea09b804c6869a09c6.tar.gz
org.eclipse.tcf-4e0d17e91c267c23b23e46ea09b804c6869a09c6.tar.xz
org.eclipse.tcf-4e0d17e91c267c23b23e46ea09b804c6869a09c6.zip
TCF Python: Implemented timer queue, added test for Task, code cleanup
Diffstat (limited to 'python/src/tcf')
-rw-r--r--python/src/tcf/channel/__init__.py4
-rw-r--r--python/src/tcf/protocol.py62
-rw-r--r--python/src/tcf/services/diagnostics.py18
-rw-r--r--python/src/tcf/services/disassembly.py4
-rw-r--r--python/src/tcf/services/filesystem.py2
-rw-r--r--python/src/tcf/services/memorymap.py4
-rw-r--r--python/src/tcf/services/pathmap.py4
-rw-r--r--python/src/tcf/services/processes_v1.py2
-rw-r--r--python/src/tcf/services/runcontrol.py12
-rw-r--r--python/src/tcf/services/stacktrace.py14
-rw-r--r--python/src/tcf/services/streams.py12
-rw-r--r--python/src/tcf/services/symbols.py20
-rw-r--r--python/src/tcf/services/sysmonitor.py6
-rw-r--r--python/src/tcf/services/terminals.py4
-rw-r--r--python/src/tcf/tests/BasicTests.py62
-rw-r--r--python/src/tcf/util/task.py58
16 files changed, 175 insertions, 113 deletions
diff --git a/python/src/tcf/channel/__init__.py b/python/src/tcf/channel/__init__.py
index b66708adb..c6c47974a 100644
--- a/python/src/tcf/channel/__init__.py
+++ b/python/src/tcf/channel/__init__.py
@@ -68,9 +68,9 @@ class ChannelListener(object):
def onChannelClosed(self, error):
"""
Called when channel closed. If it is closed because of an error,
- 'error' parameter will describe the error. 'error' is null if channel
+ 'error' parameter will describe the error. 'error' is None if channel
is closed normally by calling Channel.close().
- @param error - channel exception or null
+ @param error - channel exception or None
"""
pass
diff --git a/python/src/tcf/protocol.py b/python/src/tcf/protocol.py
index 9dfcf558e..96b91d18c 100644
--- a/python/src/tcf/protocol.py
+++ b/python/src/tcf/protocol.py
@@ -19,18 +19,25 @@ It also provides utility methods for posting asynchronous events,
including delayed events (timers).
"""
-import sys, uuid, threading
+import sys, uuid, threading, time
from EventQueue import EventQueue
_event_queue = None
+_timer_dispatcher = None
+
def startEventQueue():
- global _event_queue
+ global _event_queue, _timer_dispatcher
if _event_queue and not _event_queue.isShutdown(): return
_event_queue = EventQueue()
_event_queue.start()
# initialize LocatorService
from services.local.LocatorService import LocatorService
_event_queue.invokeLater(LocatorService)
+ # start timer dispatcher
+ _timer_dispatcher = threading.Thread(target = _dispatch_timers)
+ _timer_dispatcher.setName("TCF Timer Dispatcher")
+ _timer_dispatcher.setDaemon(True)
+ _timer_dispatcher.start()
def getEventQueue():
"""
@@ -78,11 +85,9 @@ def invokeLaterWithDelay(delay, callable, *args, **kwargs):
if delay <= 0:
_event_queue.invokeLater(callable, *args, **kwargs)
else:
- # TODO timer_queue
- raise NotImplementedError("Implement invokeLaterWithDelay")
-# synchronized (timer_queue) {
-# timer_queue.add(new Timer(System.currentTimeMillis() + delay, runnable))
-# timer_queue.notify()
+ with _timer_queue_lock:
+ _timer_queue.append(Timer(time.time() + delay /1000., callable, *args, **kwargs))
+ _timer_queue_lock.notify()
def invokeAndWait(callable, *args, **kwargs):
"""
@@ -134,7 +139,7 @@ def log(msg, x=None):
@see #setLogger
This method can be invoked from any thread.
@param msg - log entry text
- @param x - an exception associated with the log entry or null.
+ @param x - an exception associated with the log entry or None.
"""
if not _logger:
print>>sys.stderr, msg
@@ -318,3 +323,44 @@ def removeTransportProvider(provider):
"""
import transport
transport.removeTransportProvider(provider)
+
+class Timer(object):
+ timer_cnt = 0
+ def __init__(self, time, run, *args, **kwargs):
+ self.id = Timer.timer_cnt
+ Timer.timer_cnt += 1
+ self.time = time
+ self.run = run
+ self.args = args
+ self.kwargs = kwargs
+
+ def __cmp__(self, x):
+ if x is self: return 0
+ if self.time < x.time: return -1
+ if self.time > x.time: return +1
+ if self.id < x.id: return -1
+ if self.id > x.id: return +1
+ assert False
+ return 0
+
+_timer_queue_lock = threading.Condition()
+_timer_queue = []
+def _dispatch_timers():
+ try:
+ with _timer_queue_lock:
+ while True:
+ if not _timer_queue:
+ _timer_queue_lock.wait()
+ else:
+ tm = time.time()
+ t = _timer_queue[0]
+ if t.time > tm:
+ _timer_queue_lock.wait(t.time - tm)
+ else:
+ _timer_queue.pop(0)
+ invokeLater(t.run, *t.args, **t.kwargs)
+ except RuntimeError:
+ # Event queue is shut down, exit this thread
+ pass
+ except Exception as x:
+ log("Exception in TCF dispatch loop", x)
diff --git a/python/src/tcf/services/diagnostics.py b/python/src/tcf/services/diagnostics.py
index aee1ac04a..54bfa2050 100644
--- a/python/src/tcf/services/diagnostics.py
+++ b/python/src/tcf/services/diagnostics.py
@@ -141,7 +141,7 @@ class DoneEcho(object):
"""
Called when 'echo' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param s - same string as the command argument.
"""
pass
@@ -154,7 +154,7 @@ class DoneEchoFP(object):
"""
Called when 'echoFP' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param n - same number as the command argument.
"""
pass
@@ -167,7 +167,7 @@ class DoneEchoERR(object):
"""
Called when 'echoERR' command is done.
@param token - command handle.
- @param error - communication error report or null.
+ @param error - communication error report or None.
@param error_obj - error object, should be equal to the command argument.
@param error_msg - error object converted to a human readable string.
"""
@@ -181,7 +181,7 @@ class DoneGetTestList(object):
"""
Called when 'getTestList' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param list - names of tests that are supported by the peer.
"""
pass
@@ -194,7 +194,7 @@ class DoneRunTest(object):
"""
Called when 'runTest' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param context_id - test execution contest ID.
"""
pass
@@ -207,7 +207,7 @@ class DoneCancelTest(object):
"""
Called when 'cancelTest' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
@@ -219,7 +219,7 @@ class DoneGetSymbol(object):
"""
Called when 'getSymbol' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param symbol
"""
pass
@@ -257,7 +257,7 @@ class DoneCreateTestStreams(object):
"""
Called when 'createTestStreams' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param inp_id - the input stream ID.
@param out_id - the output stream ID.
"""
@@ -271,7 +271,7 @@ class DoneDisposeTestStream(object):
"""
Called when 'createTestStreams' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
diff --git a/python/src/tcf/services/disassembly.py b/python/src/tcf/services/disassembly.py
index 66ce50628..18abad1ae 100644
--- a/python/src/tcf/services/disassembly.py
+++ b/python/src/tcf/services/disassembly.py
@@ -81,7 +81,7 @@ class DoneGetCapabilities(object):
"""
Called when capabilities retrieval is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param capabilities - array of capabilities, see CAPABILITY_* for contents of each array element.
"""
pass
@@ -94,7 +94,7 @@ class DoneDisassemble(object):
"""
Called when disassembling is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param disassembly - array of disassembly lines.
"""
pass
diff --git a/python/src/tcf/services/filesystem.py b/python/src/tcf/services/filesystem.py
index 3bba2c0fd..524bea907 100644
--- a/python/src/tcf/services/filesystem.py
+++ b/python/src/tcf/services/filesystem.py
@@ -286,7 +286,7 @@ class FileSystemService(services.Service):
can from the file (up to 'len'), and return them in a byte array.
If an error occurs or EOF is encountered, the server may return
fewer bytes then requested. Call back method doneRead() argument 'error'
- will be not null in case of error, and argument 'eof' will be
+ will be not None in case of error, and argument 'eof' will be
True in case of EOF. For normal disk files, it is guaranteed
that this will read the specified number of bytes, or up to end of file
or error. For e.g. device files this may return fewer bytes than requested.
diff --git a/python/src/tcf/services/memorymap.py b/python/src/tcf/services/memorymap.py
index 1c80bad96..4b805fe97 100644
--- a/python/src/tcf/services/memorymap.py
+++ b/python/src/tcf/services/memorymap.py
@@ -160,7 +160,7 @@ class DoneGet(object):
def doneGet(self, token, error, map):
"""
Called when memory map data retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param map - memory map data.
"""
pass
@@ -172,7 +172,7 @@ class DoneSet(object):
def doneSet(self, token, error):
"""
Called when memory map set command is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
"""
pass
diff --git a/python/src/tcf/services/pathmap.py b/python/src/tcf/services/pathmap.py
index fd5cb3704..c232f15ef 100644
--- a/python/src/tcf/services/pathmap.py
+++ b/python/src/tcf/services/pathmap.py
@@ -135,7 +135,7 @@ class DoneGet(object):
def doneGet(self, token, error, map):
"""
Called when file path mapping retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param map - file path mapping data.
"""
pass
@@ -147,7 +147,7 @@ class DoneSet(object):
def doneSet(self, token, error):
"""
Called when file path mapping transmission is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param map - memory map data.
"""
pass
diff --git a/python/src/tcf/services/processes_v1.py b/python/src/tcf/services/processes_v1.py
index d77706124..83e42645f 100644
--- a/python/src/tcf/services/processes_v1.py
+++ b/python/src/tcf/services/processes_v1.py
@@ -39,7 +39,7 @@ class ProcessesV1Service(processes.ProcessesService):
Note: the service does NOT add image file name as first argument for the process.
If a client wants first parameter to be the file name, it should add it itself.
@param environment - map of environment variables for the process,
- if null then default set of environment variables will be used.
+ if None then default set of environment variables will be used.
@param params - additional process start parameters, see START_*.
@param done - call back interface called when operation is completed.
@return pending command handle, can be used to cancel the command.
diff --git a/python/src/tcf/services/runcontrol.py b/python/src/tcf/services/runcontrol.py
index cd48f40fe..d99010e1e 100644
--- a/python/src/tcf/services/runcontrol.py
+++ b/python/src/tcf/services/runcontrol.py
@@ -168,7 +168,7 @@ class RunControlService(services.Service):
"""
Retrieve children of given context.
- @param parent_context_id - parent context ID. Can be null -
+ @param parent_context_id - parent context ID. Can be None -
to retrieve top level of the hierarchy, or one of context IDs retrieved
by previous getContext or getChildren commands.
@param done - callback interface called when operation is completed.
@@ -198,7 +198,7 @@ class DoneGetState(object):
"""
Called when getState command execution is complete.
@param token - pending command handle.
- @param error - command execution error or null.
+ @param error - command execution error or None.
@param suspended - true if the context is suspended
@param pc - program counter of the context (if suspended).
@param reason - suspend reason (if suspended), see REASON_*.
@@ -211,7 +211,7 @@ class DoneCommand(object):
"""
Called when run control command execution is complete.
@param token - pending command handle.
- @param error - command execution error or null.
+ @param error - command execution error or None.
"""
pass
@@ -220,7 +220,7 @@ class DoneGetContext(object):
def doneGetContext(self, token, error, context):
"""
Called when context data retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context - context data.
"""
pass
@@ -230,7 +230,7 @@ class DoneGetChildren(object):
def doneGetChildren(self, token, error, context_ids):
"""
Called when context list retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context_ids - array of available context IDs.
"""
pass
@@ -440,7 +440,7 @@ class RunControlListener(object):
"""
Called when a thread is suspended.
@param context - ID of a context that was suspended.
- @param pc - program counter of the context, can be null.
+ @param pc - program counter of the context, can be None.
@param reason - human readable description of suspend reason.
@param params - additional, target specific data about suspended context.
"""
diff --git a/python/src/tcf/services/stacktrace.py b/python/src/tcf/services/stacktrace.py
index f0d477825..0240ec1db 100644
--- a/python/src/tcf/services/stacktrace.py
+++ b/python/src/tcf/services/stacktrace.py
@@ -67,8 +67,8 @@ class DoneGetContext(object):
def doneGetContext(self, token, error, contexts):
"""
Called when context data retrieval is done.
- @param error - error description if operation failed, null if succeeded.
- @param contexts - array of context data or null if error.
+ @param error - error description if operation failed, None if succeeded.
+ @param contexts - array of context data or None if error.
"""
pass
@@ -79,7 +79,7 @@ class DoneGetChildren(object):
def doneGetChildren(self, token, error, context_ids):
"""
Called when context list retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context_ids - array of available context IDs.
Stack frames are ordered from stack bottom to top.
"""
@@ -112,7 +112,7 @@ class StackTraceContext(object):
def getName(self):
"""
Get context name - if context represents a stack.
- @return context name or null.
+ @return context name or None.
"""
return self._props.get(PROP_NAME)
@@ -127,7 +127,7 @@ class StackTraceContext(object):
"""
Get program counter saved in this stack frame -
it is address of instruction to be executed when the function returns.
- @return return address or null if not a stack frame.
+ @return return address or None if not a stack frame.
"""
return self._props.get(PROP_RETURN_ADDRESS)
@@ -136,7 +136,7 @@ class StackTraceContext(object):
Get address of the next instruction to be executed in this stack frame.
For top frame it is same as PC register value.
For other frames it is same as return address of the next frame.
- @return instruction address or null if not a stack frame.
+ @return instruction address or None if not a stack frame.
"""
return self._props.get(PROP_INSTRUCTION_ADDRESS)
@@ -150,7 +150,7 @@ class StackTraceContext(object):
def getArgumentsAddress(self):
"""
Get address of function arguments area in memory.
- @return function arguments address or null if not available.
+ @return function arguments address or None if not available.
"""
return self._props.get(PROP_ARGUMENTS_ADDRESS, 0)
diff --git a/python/src/tcf/services/streams.py b/python/src/tcf/services/streams.py
index 1385ca0b4..283c77e30 100644
--- a/python/src/tcf/services/streams.py
+++ b/python/src/tcf/services/streams.py
@@ -129,7 +129,7 @@ class StreamsListener(object):
Called when a new stream is created.
@param stream_type - source type of the stream.
@param stream_id - ID of the stream.
- @param context_id - a context ID that is associated with the stream, or null.
+ @param context_id - a context ID that is associated with the stream, or None.
Exact meaning of the context ID depends on stream type.
Stream types and context IDs are defined by services that use Streams service to transmit data.
"""
@@ -165,7 +165,7 @@ class DoneRead(object):
"""
Called when 'read' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
@param lost_size - number of bytes that were lost because of buffer overflow.
'lost_size' -1 means unknown number of bytes were lost.
if both 'lost_size' and 'data.length' are non-zero then lost bytes are considered
@@ -183,7 +183,7 @@ class DoneWrite(object):
"""
Called when 'write' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
@@ -195,7 +195,7 @@ class DoneEOS(object):
"""
Called when 'eos' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
@@ -207,7 +207,7 @@ class DoneConnect(object):
"""
Called when 'connect' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
@@ -219,6 +219,6 @@ class DoneDisconnect(object):
"""
Called when 'disconnect' command is done.
@param token - command handle.
- @param error - error object or null.
+ @param error - error object or None.
"""
pass
diff --git a/python/src/tcf/services/symbols.py b/python/src/tcf/services/symbols.py
index 807ee6cca..9e3e8df75 100644
--- a/python/src/tcf/services/symbols.py
+++ b/python/src/tcf/services/symbols.py
@@ -110,7 +110,7 @@ class Symbol(object):
def getName(self):
"""
Get symbol name.
- @return symbol name or null.
+ @return symbol name or None.
"""
return self._props.get(PROP_NAME)
@@ -144,7 +144,7 @@ class Symbol(object):
array type - return element type
function type - return function result type
class type - return base class
- otherwise return null.
+ otherwise return None.
@return type ID.
"""
return self._props.get(PROP_BASE_TYPE_ID)
@@ -154,7 +154,7 @@ class Symbol(object):
Get index type ID.
If this symbol is a
array type - return array index type
- otherwise return null.
+ otherwise return None.
@return type ID.
"""
return self._props.get(PROP_INDEX_TYPE_ID)
@@ -197,7 +197,7 @@ class Symbol(object):
def getAddress(self):
"""
Return address of the symbol.
- @return address or null.
+ @return address or None.
"""
return self._props.get(PROP_ADDRESS)
@@ -218,7 +218,7 @@ class Symbol(object):
def getRegisterID(self):
"""
Return register ID if the symbol represents a register variable.
- @return register ID or null.
+ @return register ID or None.
"""
return self._props.get(PROP_REGISTER)
@@ -311,7 +311,7 @@ class DoneGetContext(object):
"""
Called when context data retrieval is done.
@param token - command handle
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context - context properties.
"""
pass
@@ -323,7 +323,7 @@ class DoneGetChildren(object):
"""
Called when context list retrieval is done.
@param token - command handle
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context_ids - array of available context IDs.
"""
pass
@@ -336,7 +336,7 @@ class DoneFind(object):
"""
Called when symbol search is done.
@param token - command handle.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param symbol_id - symbol ID.
"""
pass
@@ -349,7 +349,7 @@ class DoneList(object):
"""
Called when symbol list retrieval is done.
@param token - command handle.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param symbol_ids - array of symbol IDs.
"""
@@ -382,7 +382,7 @@ class DoneFindFrameInfo(object):
"""
Called when stack tracing information retrieval is done.
@param token - command handle.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param address - start of instruction address range
@param size - size of instruction address range
@param fp_cmds - commands to calculate stack frame pointer
diff --git a/python/src/tcf/services/sysmonitor.py b/python/src/tcf/services/sysmonitor.py
index 2eb05ec18..7c313a70a 100644
--- a/python/src/tcf/services/sysmonitor.py
+++ b/python/src/tcf/services/sysmonitor.py
@@ -349,7 +349,7 @@ class SysMonitorService(services.Service):
"""
Retrieve children of given context.
- @param parent_context_id - parent context ID. Can be null -
+ @param parent_context_id - parent context ID. Can be None -
to retrieve top level of the hierarchy, or one of context IDs retrieved
by previous getContext or getChildren commands.
@param done - callback interface called when operation is completed.
@@ -376,7 +376,7 @@ class DoneGetContext(object):
def doneGetContext(self, token, error, context):
"""
Called when context data retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context - context data.
"""
pass
@@ -388,7 +388,7 @@ class DoneGetChildren(object):
def doneGetChildren(self, token, error, context_ids):
"""
Called when context list retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context_ids - array of available context IDs.
"""
pass
diff --git a/python/src/tcf/services/terminals.py b/python/src/tcf/services/terminals.py
index 28c49896b..a41d90a67 100644
--- a/python/src/tcf/services/terminals.py
+++ b/python/src/tcf/services/terminals.py
@@ -136,7 +136,7 @@ class TerminalsService(services.Service):
@param type - requested terminal type for the new terminal.
@param encoding - requested encoding for the new terminal.
@param environment - Array of environment variable strings.
- if null then default set of environment variables will be used.
+ if None then default set of environment variables will be used.
@param done - call back interface called when operation is completed.
@return pending command handle, can be used to cancel the command.
"""
@@ -183,7 +183,7 @@ class DoneGetContext(object):
def doneGetContext(self, token, error, context):
"""
Called when contexts data retrieval is done.
- @param error - error description if operation failed, null if succeeded.
+ @param error - error description if operation failed, None if succeeded.
@param context - context data.
"""
pass
diff --git a/python/src/tcf/tests/BasicTests.py b/python/src/tcf/tests/BasicTests.py
index 2db495a52..7e3bbb9cf 100644
--- a/python/src/tcf/tests/BasicTests.py
+++ b/python/src/tcf/tests/BasicTests.py
@@ -28,6 +28,7 @@ _memory = []
def test():
protocol.startEventQueue()
+ #testTimer()
try:
c = tcf.connect("TCP:127.0.0.1:1534")
except Exception as e:
@@ -49,6 +50,7 @@ def test():
testExpressions(c)
testLineNumbers(c)
testSyncCommands(c)
+ testTasks(c)
testEvents(c)
testDataCache(c)
testProcesses(c)
@@ -65,6 +67,22 @@ def test():
protocol.invokeLater(c.close)
time.sleep(2)
+
+def testTimer():
+ cond = threading.Condition()
+ def countdown(left):
+ if left == 0:
+ print "Ignition sequence started!"
+ with cond:
+ cond.notify()
+ return
+ print "%d seconds to go" % left
+ sys.stdout.flush()
+ protocol.invokeLaterWithDelay(1000, countdown, left - 1)
+ with cond:
+ protocol.invokeLaterWithDelay(0, countdown, 10)
+ cond.wait(15)
+
def testRunControl(c):
lock = threading.Condition()
from tcf.services import runcontrol
@@ -112,7 +130,7 @@ def testRunControl(c):
pending.append(rctrl.getChildren(None, DoneGetChildren()))
with lock:
protocol.invokeLater(getContexts)
- lock.wait(5000)
+ lock.wait(5)
def listenerTest():
rc = c.getRemoteService(runcontrol.NAME)
class RCListener(runcontrol.RunControlListener):
@@ -146,7 +164,7 @@ def testRunControl(c):
if _suspended:
with lock:
protocol.invokeLater(listenerTest)
- lock.wait(5000)
+ lock.wait(5)
def testBreakpoints(c):
from tcf.services import breakpoints
@@ -236,8 +254,9 @@ def testDisassembly(c):
if addr:
print "Disassemble context %s from 0x%x" % (ctx_id, addr)
lines = dis.disassemble(ctx_id, addr, 256, None).get()
- for line in lines:
- print line
+ if lines:
+ for line in lines:
+ print line
def testSymbols(c):
from tcf.services import symbols
@@ -319,7 +338,7 @@ def testRegisters(c):
with lock:
for ctx_id in _suspended:
protocol.invokeLater(regTest, ctx_id)
- lock.wait(5000)
+ lock.wait(5)
def testExpressions(c):
if not _suspended: return
@@ -381,6 +400,27 @@ def testSyncCommands(c):
except:
pass # no Processes service
+def testTasks(c):
+ if not _suspended: return
+ from tcf.services import expressions
+ from tcf.util import task
+ def compute(expr, done=None):
+ es = c.getRemoteService(expressions.NAME)
+ if not es:
+ done(Exception("No Expressions service"), None)
+ return
+ def doneCreate(token, error, ctx):
+ if error:
+ done(error, None)
+ return
+ def doneEval(token, error, val):
+ done(error, val)
+ es.evaluate(ctx.getID(), doneEval)
+ es.create(_suspended[0], None, expr, doneCreate)
+ t = task.Task(compute, "1+2*(3-4/2)", channel=c)
+ val = t.get()
+ print "Task result:", val
+
def testEvents(c):
from tcf.util import event
recorder = event.EventRecorder(c)
@@ -488,7 +528,7 @@ def testMemory(c):
pending.append(mem.getChildren(None, DoneGetChildren()))
with lock:
protocol.invokeLater(getContexts)
- lock.wait(5000)
+ lock.wait(5)
def testMemoryMap(c):
if not _memory: return
@@ -514,7 +554,7 @@ def testMemoryMap(c):
mm.get(id, DoneGet())
with lock:
protocol.invokeLater(getMap)
- lock.wait(1000)
+ lock.wait(1)
def setMap():
mm = c.getRemoteService(memorymap.NAME)
class DoneSet(memorymap.DoneSet):
@@ -526,7 +566,7 @@ def testMemoryMap(c):
mm.set(id, {memorymap.PROP_FILE_NAME : "/tmp/system.elf"}, DoneSet())
with lock:
protocol.invokeLater(setMap)
- lock.wait(1000)
+ lock.wait(1)
map = mm.get(id).get()
print "Memory map:", map
@@ -552,7 +592,7 @@ def testPathMap(c):
pm.get(DoneGet())
with lock:
protocol.invokeLater(getMap)
- lock.wait(1000)
+ lock.wait(1)
def setMap():
pm = c.getRemoteService(pathmap.NAME)
class DoneSet(pathmap.DoneSet):
@@ -565,7 +605,7 @@ def testPathMap(c):
pathmap.PROP_DESTINATION : "/home"}, DoneSet())
with lock:
protocol.invokeLater(setMap)
- lock.wait(1000)
+ lock.wait(1)
map = pm.get().get()
print "Path map:", map
@@ -606,7 +646,7 @@ def testSysMonitor(c):
pending.append(sm.getChildren(None, DoneGetChildren()))
with lock:
protocol.invokeLater(getProcesses)
- lock.wait(5000)
+ lock.wait(5)
print "%d processes found:" % len(processes)
for p in processes:
print p
diff --git a/python/src/tcf/util/task.py b/python/src/tcf/util/task.py
index 8c4e3ed92..77f5bab36 100644
--- a/python/src/tcf/util/task.py
+++ b/python/src/tcf/util/task.py
@@ -10,7 +10,7 @@
#******************************************************************************
import threading
-from tcf import protocol
+from tcf import protocol, channel
class Task(object):
"""
@@ -32,7 +32,7 @@ class Task(object):
__is_done = False
__error = None
__canceled = False
- __channel = None
+ __channel_listener = None
def __init__(self, target=None, *args, **kwargs):
"""
@@ -47,47 +47,23 @@ class Task(object):
self._args = args
self._kwargs = kwargs
self._lock = threading.Condition()
+ self.__channel = kwargs.pop("channel", None)
protocol.invokeLater(self.__doRun)
- timeout = kwargs.get("timeout")
+ timeout = kwargs.pop("timeout", None)
if timeout:
protocol.invokeLaterWithDelay(timeout, self.cancel)
-# """
-# Construct a TCF task object and schedule it for execution.
-# The task will be __canceled if the given __channel is closed or
-# terminated while the task is in progress.
-# @param __channel
-# """
-# public Task(final IChannel __channel) {
-# Protocol.invokeLater(new Runnable() {
-# public void run() {
-# try {
-# if (__channel.getState() != IChannel.STATE_OPEN) throw new Exception("Channel is closed")
-# Task.this.__channel = __channel
-# channel_listener = new IChannel.IChannelListener() {
-#
-# public void congestionLevel(int level) {
-# }
-#
-# public void onChannelClosed(final Throwable __error) {
-# cancel(true)
-# }
-#
-# public void onChannelOpened() {
-# }
-# }
-# __channel.addChannelListener(channel_listener)
-# Task.this.run()
-# }
-# catch (Throwable x) {
-# if (!__is_done && __error == null) error(x)
-# }
-# }
-# })
-# }
-
def __doRun(self):
try:
+ if self.__channel:
+ if self.__channel.getState() != channel.STATE_OPEN:
+ raise Exception("Channel is closed")
+ task = self
+ class CancelOnClose(channel.ChannelListener):
+ def onChannelClosed(self, error):
+ task.cancel(True)
+ self.__channel_listener = CancelOnClose()
+ self.__channel.addChannelListener(self.__channel_listener)
self._target(*self._args, **self._kwargs)
except Exception as x:
if not self.__is_done and self.__error is None:
@@ -112,7 +88,7 @@ class Task(object):
self.__result = result
self.__is_done = True
if self.__channel:
- self.__channel.removeChannelListener(self.channel_listener)
+ self.__channel.removeChannelListener(self.__channel_listener)
self._lock.notifyAll()
def error(self, error):
@@ -131,7 +107,7 @@ class Task(object):
assert not self.__is_done
self.__error = error
if self.__channel:
- self.__channel.removeChannelListener(self.channel_listener)
+ self.__channel.removeChannelListener(self.__channel_listener)
self._lock.notifyAll()
def cancel(self):
@@ -141,7 +117,7 @@ class Task(object):
self.__canceled = True
self.__error = Exception("Canceled")
if self.__channel:
- self.__channel.removeChannelListener(self.channel_listener)
+ self.__channel.removeChannelListener(self.__channel_listener)
self._lock.notifyAll()
return True
@@ -193,7 +169,7 @@ class Task(object):
def getError(self):
"""
Return task execution __error if any.
- @return Throwable object or null
+ @return Throwable object or None
"""
return self.__error

Back to the top