diff options
author | Frederic Leger | 2013-01-16 08:34:18 +0000 |
---|---|---|
committer | Anton Leherbauer | 2013-01-16 08:34:18 +0000 |
commit | 7997d52dc1d0e5a24de734a80016c65329cc9149 (patch) | |
tree | fe155ca75d2b22b3789737c82e696f45d61807fd /python | |
parent | 61435e0455753f81c20f42b9eef51f925da293ba (diff) | |
download | org.eclipse.tcf-7997d52dc1d0e5a24de734a80016c65329cc9149.tar.gz org.eclipse.tcf-7997d52dc1d0e5a24de734a80016c65329cc9149.tar.xz org.eclipse.tcf-7997d52dc1d0e5a24de734a80016c65329cc9149.zip |
TCF Python: Bug 397827 - Use relative imports inside tcf package modules
Diffstat (limited to 'python')
62 files changed, 1983 insertions, 1060 deletions
diff --git a/python/src/tcf/EventQueue.py b/python/src/tcf/EventQueue.py index bb8eb6276..1265b1972 100644 --- a/python/src/tcf/EventQueue.py +++ b/python/src/tcf/EventQueue.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -10,7 +10,6 @@ # ***************************************************************************** import threading -import protocol class EventQueue(object): @@ -39,6 +38,7 @@ class EventQueue(object): self.__lock.notifyAll() self.__thread.join() except Exception as e: + from . import protocol protocol.log("Failed to shutdown TCF event dispatch thread", e) def isShutdown(self): @@ -46,6 +46,7 @@ class EventQueue(object): return self.__is_shutdown def __error(self, x): + from . import protocol protocol.log("Unhandled exception in TCF event dispatch", x) def __call__(self): diff --git a/python/src/tcf/__init__.py b/python/src/tcf/__init__.py index 9978c6234..ec5e6b937 100644 --- a/python/src/tcf/__init__.py +++ b/python/src/tcf/__init__.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,21 +7,24 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** """ TCF - Target Communication Framework """ import types -import protocol, peer, channel -from util import task + +from . import protocol, peer, channel +from .util import task __all__ = ('connect') + def connect(params, wait=True): - """Connect to peer. Argument is a string of the form <transport>:<host>:<port>, - e.g. "TCP:127.0.0.1:1534" """ + """Connect to peer. Argument is a string of the form + <transport>:<host>:<port>, e.g. "TCP:127.0.0.1:1534". + """ if type(params) is types.StringType: params = _parse_params(params) elif type(params) is not types.DictType: @@ -33,24 +36,30 @@ def connect(params, wait=True): c = protocol.invokeAndWait(p.openChannel) return c + def peers(): "Return list of discovered remote peers" locator = protocol.getLocator() if locator: return protocol.invokeAndWait(locator.getPeers) + def _openChannel(p, done=None): assert protocol.isDispatchThread() c = p.openChannel() - if done is None: return + if done is None: + return + class ChannelListener(channel.ChannelListener): def onChannelOpened(self): c.removeChannelListener(self) done(None, c) + def onChannelClosed(self, error): done(error, None) c.addChannelListener(ChannelListener()) + def _parse_params(paramStr): args = paramStr.split(":") if len(args) != 3: diff --git a/python/src/tcf/channel/AbstractChannel.py b/python/src/tcf/channel/AbstractChannel.py index f313cc252..e700af122 100644 --- a/python/src/tcf/channel/AbstractChannel.py +++ b/python/src/tcf/channel/AbstractChannel.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,16 +7,20 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** -import sys, threading, time, types -from tcf import protocol, transport, services, peer, errors -from tcf.services import locator -from tcf.channel import STATE_CLOSED, STATE_OPEN, STATE_OPENING -from tcf.channel import Token, fromJSONSequence, toJSONSequence +import sys +import threading +import time +import types -EOS = -1 # End Of Stream -EOM = -2 # End Of Message +from .. import protocol, transport, services, peer, errors +from ..services import locator +from ..channel import STATE_CLOSED, STATE_OPEN, STATE_OPENING +from ..channel import Token, fromJSONSequence, toJSONSequence + +EOS = -1 # End Of Stream +EOM = -2 # End Of Message class Message(object): @@ -31,9 +35,11 @@ class Message(object): self.is_sent = None self.token = None self.trace = () + def __str__(self): return "%s %s %s" % (self.type, self.service, self.name) + class ReaderThread(threading.Thread): def __init__(self, channel, handleInput): super(ReaderThread, self).__init__(name="TCF Reader Thread") @@ -52,9 +58,13 @@ class ReaderThread(threading.Thread): while True: n = self.channel.read() if n <= 0: - if n == end: break - if n == EOM: raise IOError("Unexpected end of message") - if n < 0: raise IOError("Communication channel is closed by remote peer") + if n == end: + break + if n == EOM: + raise IOError("Unexpected end of message") + if n < 0: + raise IOError("Communication channel is closed by " + \ + "remote peer") buf.append(n) return buf @@ -66,18 +76,21 @@ class ReaderThread(threading.Thread): try: while True: n = self.channel.read() - if n == EOM: continue + if n == EOM: + continue if n == EOS: try: self.eos_err_report = self.readBytes(EOM) reportLen = len(self.eos_err_report) - if reportLen == 0 or reportLen == 1 and self.eos_err_report[0] == 0: + if reportLen == 0 or reportLen == 1 and \ + self.eos_err_report[0] == 0: self.eos_err_report = None except: pass break msg = Message(n) - if self.channel.read() != 0: self.error() + if self.channel.read() != 0: + self.error() typeCode = msg.type if typeCode == 'C': msg.token = Token(self.readBytes(0)) @@ -97,7 +110,8 @@ class ReaderThread(threading.Thread): self.error() protocol.invokeLater(self.handleInput, msg) delay = self.channel.local_congestion_level - if delay > 0: time.sleep(delay / 1000.0) + if delay > 0: + time.sleep(delay / 1000.0) protocol.invokeLater(self.handleEOS) except Exception as x: try: @@ -124,18 +138,22 @@ class ReaderThread(threading.Thread): class AbstractChannel(object): """ - AbstractChannel implements communication link connecting two end points (peers). - The channel asynchronously transmits messages: commands, results and events. + AbstractChannel implements communication link connecting two end points + (peers). + The channel asynchronously transmits messages: commands, results and + events. - Clients can subclass AbstractChannel to support particular transport (wire) protocol. + Clients can subclass AbstractChannel to support particular transport (wire) + protocol. Also, see StreamChannel for stream oriented transport protocols. """ def __init__(self, remote_peer, local_peer=None): self.remote_peer = remote_peer - self.local_peer = local_peer # TODO + self.local_peer = local_peer # TODO self.inp_thread = ReaderThread(self, self.__handleInput) - self.out_thread = threading.Thread(target=self.__write_output,name="TCF Channel Transmitter") + self.out_thread = threading.Thread(target=self.__write_output, + name="TCF Channel Transmitter") self.out_thread.daemon = True self.out_tokens = {} self.out_queue = [] @@ -171,10 +189,12 @@ class AbstractChannel(object): while len(self.out_queue) == 0: self.out_lock.wait() msg = self.out_queue.pop(0) - if not msg: break + if not msg: + break last = len(self.out_queue) == 0 if msg.is_canceled: - if last: self.flush() + if last: + self.flush() continue msg.is_sent = True if msg.trace: @@ -195,10 +215,13 @@ class AbstractChannel(object): self.write(EOM) delay = 0 level = self.remote_congestion_level - if level > 0: delay = level * 10 - if last or delay > 0: self.flush() - if delay > 0: time.sleep(delay / 1000.0) - #else yield() + if level > 0: + delay = level * 10 + if last or delay > 0: + self.flush() + if delay > 0: + time.sleep(delay / 1000.0) + # else yield() self.write(EOS) self.write(EOM) self.flush() @@ -212,10 +235,10 @@ class AbstractChannel(object): def __traceMessageSent(self, m): for l in m.trace: try: - id = None + tokenID = None if m.token is not None: - id = m.token.getID() - l.onMessageSent(m.type, id, m.service, m.name, m.data) + tokenID = m.token.getID() + l.onMessageSent(m.type, tokenID, m.service, m.name, m.data) except Exception as x: protocol.log("Exception in channel listener", x) @@ -227,34 +250,42 @@ class AbstractChannel(object): def __initServices(self): try: - if self.proxy: return - if self.state == STATE_CLOSED: return + if self.proxy: + return + if self.state == STATE_CLOSED: + return services.onChannelCreated(self, self.local_service_by_name) - self.__makeServiceByClassMap(self.local_service_by_name, self.local_service_by_class) + self.__makeServiceByClassMap(self.local_service_by_name, + self.local_service_by_class) args = self.local_service_by_name.keys() - self.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((args,))) + self.sendEvent(protocol.getLocator(), "Hello", + toJSONSequence((args,))) except IOError as x: self.terminate(x) def redirect_id(self, peer_id): """ - Redirect this channel to given peer using this channel remote peer locator service as a proxy. - @param peer_id - peer that will become new remote communication endpoint of this channel + Redirect this channel to given peer using this channel remote peer + locator service as a proxy. + @param peer_id - peer that will become new remote communication + endpoint of this channel """ - map = {} - map[peer.ATTR_ID] = peer_id + peerMap = {} + peerMap[peer.ATTR_ID] = peer_id self.redirect(map) def redirect(self, peer_attrs): """ - Redirect this channel to given peer using this channel remote peer locator service as a proxy. - @param peer_attrs - peer that will become new remote communication endpoint of this channel + Redirect this channel to given peer using this channel remote peer + locator service as a proxy. + @param peer_attrs - peer that will become new remote communication + endpoint of this channel """ if isinstance(peer_attrs, str): # support for redirect(peerId) - map = {} - map[peer.ATTR_ID] = peer_attrs - peer_attrs = map + attrs = {} + attrs[peer.ATTR_ID] = peer_attrs + peer_attrs = attrs channel = self assert protocol.isDispatchThread() if self.state == STATE_OPENING: @@ -264,20 +295,28 @@ class AbstractChannel(object): assert self.redirect_command is None try: l = self.remote_service_by_class.get(locator.LocatorService) - if not l: raise IOError("Cannot redirect channel: peer " + - self.remote_peer.getID() + " has no locator service") + if not l: + raise IOError("Cannot redirect channel: peer " + + self.remote_peer.getID() + + " has no locator service") peer_id = peer_attrs.get(peer.ATTR_ID) if peer_id and len(peer_attrs) == 1: _peer = l.getPeers().get(peer_id) if not _peer: - # Peer not found, must wait for a while until peer is discovered or time out + # Peer not found, must wait for a while until peer is + # discovered or time out class Callback(object): found = None + def __call__(self): - if self.found: return - channel.terminate(Exception("Peer " + peer_id + " not found")) + if self.found: + return + channel.terminate(Exception("Peer " + peer_id + + " not found")) cb = Callback() - protocol.invokeLaterWithDelay(locator.DATA_RETENTION_PERIOD / 3, cb) + delay = locator.DATA_RETENTION_PERIOD / 3 + protocol.invokeLaterWithDelay(delay, cb) + class Listener(locator.LocatorListener): def peerAdded(self, new_peer): if new_peer.getID() == peer_id: @@ -291,33 +330,42 @@ class AbstractChannel(object): def doneRedirect(self, token, exc): assert channel.redirect_command is token channel.redirect_command = None - if channel.state != STATE_OPENING: return - if exc: channel.terminate(exc) + if channel.state != STATE_OPENING: + return + if exc: + channel.terminate(exc) channel.remote_peer = _peer channel.remote_service_by_class.clear() channel.remote_service_by_name.clear() channel.event_listeners.clear() - self.redirect_command = l.redirect(peer_id, DoneRedirect()) + self.redirect_command = l.redirect(peer_id, + DoneRedirect()) else: class TransientPeer(peer.TransientPeer): def __init__(self, peer_attrs, parent): super(TransientPeer, self).__init__(peer_attrs) self.parent = parent + def openChannel(self): c = self.parent.openChannel() c.redirect(peer_attrs) + class DoneRedirect(locator.DoneRedirect): def doneRedirect(self, token, exc): assert channel.redirect_command is token channel.redirect_command = None - if channel.state != STATE_OPENING: return - if exc: channel.terminate(exc) + if channel.state != STATE_OPENING: + return + if exc: + channel.terminate(exc) parent = channel.remote_peer - channel.remote_peer = TransientPeer(peer_attrs, parent) + channel.remote_peer = TransientPeer(peer_attrs, + parent) channel.remote_service_by_class.clear() channel.remote_service_by_name.clear() channel.event_listeners.clear() - self.redirect_command = l.redirect(peer_attrs, DoneRedirect()) + self.redirect_command = l.redirect(peer_attrs, + DoneRedirect()) self.state = STATE_OPENING except Exception as x: self.terminate(x) @@ -325,7 +373,8 @@ class AbstractChannel(object): def __makeServiceByClassMap(self, by_name, by_class): for service in by_name.values(): for clazz in service.__class__.__bases__: - if clazz == services.Service: continue + if clazz == services.Service: + continue # TODO # if (!IService.class.isAssignableFrom(fs)) continue by_class[clazz] = service @@ -352,27 +401,29 @@ class AbstractChannel(object): def removeTraceListener(self, listener): self.trace_listeners = self.trace_listeners[:] self.trace_listeners.remove(listener) - if len(self.trace_listeners) == 0: self.trace_listeners = None + if len(self.trace_listeners) == 0: + self.trace_listeners = None def addEventListener(self, service, listener): assert protocol.isDispatchThread() svc_name = str(service) listener.svc_name = svc_name - list = self.event_listeners.get(svc_name) or [] - list.append(listener) - self.event_listeners[svc_name] = list + lst = self.event_listeners.get(svc_name) or [] + lst.append(listener) + self.event_listeners[svc_name] = lst def removeEventListener(self, service, listener): assert protocol.isDispatchThread() svc_name = str(service) - list = self.event_listeners.get(svc_name) - if not list: return - for i in range(len(list)): - if list[i] is listener: - if len(list) == 1: + lst = self.event_listeners.get(svc_name) + if not lst: + return + for i in range(len(lst)): + if lst[i] is listener: + if len(lst) == 1: del self.event_listeners[svc_name] else: - del list[i] + del lst[i] return def addCommandServer(self, service, listener): @@ -391,7 +442,8 @@ class AbstractChannel(object): def close(self): assert protocol.isDispatchThread() - if self.state == STATE_CLOSED: return + if self.state == STATE_CLOSED: + return try: self.__sendEndOfStream(10000) self._close(None) @@ -400,11 +452,13 @@ class AbstractChannel(object): def terminate(self, error): assert protocol.isDispatchThread() - if self.state == STATE_CLOSED: return + if self.state == STATE_CLOSED: + return try: self.__sendEndOfStream(500) except Exception as x: - if not error: error = x + if not error: + error = x self._close(error) def __sendEndOfStream(self, timeout): @@ -433,17 +487,22 @@ class AbstractChannel(object): except Exception as x: protocol.log("Exception in channel listener", x) channel = self + class Runnable(object): def __call__(self): if channel.out_tokens: x = None - if isinstance(error, Exception): x = error - elif error: x = Exception(error) - else: x = IOError("Channel is closed") + if isinstance(error, Exception): + x = error + elif error: + x = Exception(error) + else: + x = IOError("Channel is closed") for msg in channel.out_tokens.values(): try: s = str(msg) - if len(s) > 72: s = s[:72] + "...]" + if len(s) > 72: + s = s[:72] + "...]" y = IOError("Command " + s + " aborted") # y.initCause(x) msg.token.getListener().terminated(msg.token, y) @@ -452,7 +511,8 @@ class AbstractChannel(object): channel.out_tokens.clear() if channel.channel_listeners: for l in channel.channel_listeners: - if not l: break + if not l: + break try: l.onChannelClosed(error) except Exception as x: @@ -470,8 +530,10 @@ class AbstractChannel(object): def getCongestion(self): assert protocol.isDispatchThread() level = len(self.out_tokens) * 100 / self.pending_command_limit - 100 - if self.remote_congestion_level > level: level = self.remote_congestion_level - if level > 100: level = 100 + if self.remote_congestion_level > level: + level = self.remote_congestion_level + if level > 100: + level = 100 return level def getLocalPeer(self): @@ -509,15 +571,21 @@ class AbstractChannel(object): return self.remote_service_by_class.get(cls_or_name) def setServiceProxy(self, service_interface, service_proxy): - if not self.notifying_channel_opened: raise Exception("setServiceProxe() can be called only from channel open call-back") - if not isinstance(self.remote_service_by_name.get(service_proxy.getName()), services.GenericProxy): raise Exception("Proxy already set") - if self.remote_service_by_class.get(service_interface): raise Exception("Proxy already set") + if not self.notifying_channel_opened: + raise Exception("setServiceProxe() can be called only from " + + "channel open call-back") + proxy = self.remote_service_by_name.get(service_proxy.getName()) + if not isinstance(proxy, services.GenericProxy): + raise Exception("Proxy already set") + if self.remote_service_by_class.get(service_interface): + raise Exception("Proxy already set") self.remote_service_by_class[service_interface] = service_proxy self.remote_service_by_name[service_proxy.getName()] = service_proxy def setProxy(self, proxy, services): self.proxy = proxy - self.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((services,))) + self.sendEvent(protocol.getLocator(), "Hello", + toJSONSequence((services,))) self.local_service_by_class.clear() self.local_service_by_name.clear() @@ -529,21 +597,27 @@ class AbstractChannel(object): def sendCommand(self, service, name, args, listener): assert protocol.isDispatchThread() - if self.state == STATE_OPENING: raise Exception("Channel is waiting for Hello message") - if self.state == STATE_CLOSED: raise Exception("Channel is closed") + if self.state == STATE_OPENING: + raise Exception("Channel is waiting for Hello message") + if self.state == STATE_CLOSED: + raise Exception("Channel is closed") msg = Message('C') msg.service = str(service) msg.name = name msg.data = args channel = self + class CancelableToken(Token): def __init__(self, listener): super(CancelableToken, self).__init__(listener=listener) + def cancel(self): assert protocol.isDispatchThread() - if channel.state != STATE_OPEN: return False + if channel.state != STATE_OPEN: + return False with channel.out_lock: - if msg.is_sent: return False + if msg.is_sent: + return False msg.is_canceled = True del channel.out_tokens[msg.token.getID()] return True @@ -555,7 +629,8 @@ class AbstractChannel(object): def sendProgress(self, token, results): assert protocol.isDispatchThread() - if self.state != STATE_OPEN: raise Exception("Channel is closed") + if self.state != STATE_OPEN: + raise Exception("Channel is closed") msg = Message('P') msg.data = results msg.token = token @@ -563,7 +638,8 @@ class AbstractChannel(object): def sendResult(self, token, results): assert protocol.isDispatchThread() - if self.state != STATE_OPEN: raise Exception("Channel is closed") + if self.state != STATE_OPEN: + raise Exception("Channel is closed") msg = Message('R') msg.data = results msg.token = token @@ -571,14 +647,16 @@ class AbstractChannel(object): def rejectCommand(self, token): assert protocol.isDispatchThread() - if self.state != STATE_OPEN: raise Exception("Channel is closed") + if self.state != STATE_OPEN: + raise Exception("Channel is closed") msg = Message('N') msg.token = token self.addToOutQueue(msg) def sendEvent(self, service, name, args): assert protocol.isDispatchThread() - if not (self.state == STATE_OPEN or self.state == STATE_OPENING and isinstance(service, locator.LocatorService)): + if not (self.state == STATE_OPEN or self.state == STATE_OPENING and + isinstance(service, locator.LocatorService)): raise Exception("Channel is closed") msg = Message('E') msg.service = str(service) @@ -592,16 +670,18 @@ class AbstractChannel(object): def __traceMessageReceived(self, m): for l in self.trace_listeners: try: - id = None + messageID = None if m.token is not None: - id = m.token.getID() - l.onMessageReceived(m.type, id, m.service, m.name, m.data) + messageID = m.token.getID() + l.onMessageReceived(m.type, messageID, m.service, m.name, + m.data) except Exception as x: protocol.log("Exception in channel listener", x) def __handleInput(self, msg): assert protocol.isDispatchThread() - if self.state == STATE_CLOSED: return + if self.state == STATE_CLOSED: + return if self.trace_listeners: self.__traceMessageReceived(msg) try: @@ -610,15 +690,18 @@ class AbstractChannel(object): if typeCode in 'PRN': token_id = msg.token.getID() cmd = self.out_tokens.get(token_id) - if cmd is None: raise Exception("Invalid token received: " + token_id) + if cmd is None: + raise Exception("Invalid token received: " + token_id) if typeCode != 'P': del self.out_tokens[token_id] token = cmd.token if typeCode == 'C': if self.state == STATE_OPENING: - raise IOError("Received command " + msg.service + "." + msg.name + " before Hello message") + raise IOError("Received command " + msg.service + "." + + msg.name + " before Hello message") if self.proxy: - self.proxy.onCommand(msg.token, msg.service, msg.name, msg.data) + self.proxy.onCommand(msg.token, msg.service, msg.name, + msg.data) else: token = msg.token cmds = self.command_servers.get(msg.service) @@ -633,16 +716,19 @@ class AbstractChannel(object): token.getListener().result(token, msg.data) self.__sendCongestionLevel() elif typeCode == 'N': - token.getListener().terminated(token, errors.ErrorReport( - "Command is not recognized", errors.TCF_ERROR_INV_COMMAND)) + report = errors.ErrorReport("Command is not recognized", + errors.TCF_ERROR_INV_COMMAND) + token.getListener().terminated(token, report) elif typeCode == 'E': hello = msg.service == locator.NAME and msg.name == "Hello" if hello: self.remote_service_by_name.clear() self.remote_service_by_class.clear() data = fromJSONSequence(msg.data)[0] - services.onChannelOpened(self, data, self.remote_service_by_name) - self.__makeServiceByClassMap(self.remote_service_by_name, self.remote_service_by_class) + services.onChannelOpened(self, data, + self.remote_service_by_name) + self.__makeServiceByClassMap(self.remote_service_by_name, + self.remote_service_by_class) self.zero_copy = "ZeroCopy" in self.remote_service_by_name if self.proxy and self.state == STATE_OPEN: self.proxy.onEvent(msg.service, msg.name, msg.data) @@ -658,21 +744,24 @@ class AbstractChannel(object): transport.channelOpened(self) self.registered_with_trasport = True for l in self.channel_listeners: - if not l: break + if not l: + break try: l.onChannelOpened() except Exception as x: - protocol.log("Exception in channel listener", x) + protocol.log("Exception in channel listener", + x) self.notifying_channel_opened = False else: - list = self.event_listeners.get(msg.service) - if list: - for l in list: + lst = self.event_listeners.get(msg.service) + if lst: + for l in lst: l.event(msg.name, msg.data) self.__sendCongestionLevel() elif typeCode == 'F': length = len(msg.data) - if length > 0 and msg.data[length - 1] == '\0': length -= 1 + if length > 0 and msg.data[length - 1] == '\0': + length -= 1 self.remote_congestion_level = int(msg.data) else: assert False @@ -682,16 +771,21 @@ class AbstractChannel(object): def __sendCongestionLevel(self): self.local_congestion_cnt += 1 - if self.local_congestion_cnt < 8: return + if self.local_congestion_cnt < 8: + return self.local_congestion_cnt = 0 - if self.state != STATE_OPEN: return + if self.state != STATE_OPEN: + return timeVal = int(time.time() * 1000) - if timeVal - self.local_congestion_time < 500: return + if timeVal - self.local_congestion_time < 500: + return assert protocol.isDispatchThread() level = protocol.getCongestionLevel() - if level == self.local_congestion_level: return + if level == self.local_congestion_level: + return i = (level - self.local_congestion_level) / 8 - if i != 0: level = self.local_congestion_level + i + if i != 0: + level = self.local_congestion_level + i self.local_congestion_time = timeVal with self.out_lock: msg = None @@ -721,7 +815,8 @@ class AbstractChannel(object): The method argument can be one of two special values: EOS (-1) end of stream marker EOM (-2) end of message marker. - The stream can put the byte into a buffer instead of transmitting it right away. + The stream can put the byte into a buffer instead of transmitting it + right away. @param n - the data byte. @raises IOError """ @@ -747,7 +842,8 @@ class AbstractChannel(object): def write(self, buf): """ Write array of bytes into the channel output stream. - The stream can put bytes into a buffer instead of transmitting it right away. + The stream can put bytes into a buffer instead of transmitting it right + away. @param buf @raises IOError """ diff --git a/python/src/tcf/channel/ChannelProxy.py b/python/src/tcf/channel/ChannelProxy.py index dc0802759..ffd502456 100644 --- a/python/src/tcf/channel/ChannelProxy.py +++ b/python/src/tcf/channel/ChannelProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,30 +7,35 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** """ ChannelProxy implements forwarding of TCF messages between two channels. The class is used to implement Locator service "redirect" command. """ -from tcf import channel +from .. import channel + class ProxyCommandListener(channel.CommandListener): def __init__(self, ch, tokens): self.ch = ch self.tokens = tokens + def progress(self, token, data): self.ch.sendProgress(self.tokens.get(token), data) + def result(self, token, data): self.ch.sendResult(self.tokens.pop(token, None), data) + def terminated(self, token, error): self.ch.rejectCommand(self.tokens.pop(token, None)) + class ChannelProxy(object): def __init__(self, x, y): - #assert not isinstance(x, ChannelLoop) - #assert not isinstance(y, ChannelLoop) + # assert not isinstance(x, ChannelLoop) + # assert not isinstance(y, ChannelLoop) self.ch_x = x self.ch_y = y assert self.ch_x.getState() == channel.STATE_OPEN @@ -44,50 +49,76 @@ class ChannelProxy(object): class ProxyX(channel.Proxy): def onChannelClosed(self, error): proxy.closed_x = True - if proxy.closed_y: return - if error is None: proxy.ch_y.close() - else: proxy.ch_y.terminate(error) + if proxy.closed_y: + return + if error is None: + proxy.ch_y.close() + else: + proxy.ch_y.terminate(error) + def onCommand(self, token, service, name, data): - if proxy.closed_y: return + if proxy.closed_y: + return assert proxy.ch_y.getState() == channel.STATE_OPEN s = proxy.ch_y.getRemoteService(service) - if not s: proxy.ch_x.terminate(IOError("Invalid service name")) - else: proxy.tokens_x[proxy.ch_y.sendCommand(s, name, data, cmd_listener_x)] = token + if not s: + proxy.ch_x.terminate(IOError("Invalid service name")) + else: + key = proxy.ch_y.sendCommand(s, name, data, cmd_listener_x) + proxy.tokens_x[key] = token + def onEvent(self, service, name, data): s = proxy.ch_x.getRemoteService(service) - if not s: proxy.ch_x.terminate(IOError("Invalid service name")) - elif not proxy.closed_y: proxy.ch_y.sendEvent(s, name, data) + if not s: + proxy.ch_x.terminate(IOError("Invalid service name")) + elif not proxy.closed_y: + proxy.ch_y.sendEvent(s, name, data) class ProxyY(channel.Proxy): def onChannelClosed(self, error): proxy.closed_y = True - if proxy.closed_x: return - if error is None: proxy.ch_x.close() - else: proxy.ch_x.terminate(error) + if proxy.closed_x: + return + if error is None: + proxy.ch_x.close() + else: + proxy.ch_x.terminate(error) + def onCommand(self, token, service, name, data): - if proxy.closed_x: return + if proxy.closed_x: + return assert proxy.ch_x.getState() == channel.STATE_OPEN s = proxy.ch_x.getRemoteService(service) - if not s: proxy.ch_y.terminate(IOError("Invalid service name")) - else: proxy.tokens_y[proxy.ch_x.sendCommand(s, name, data, cmd_listener_y)] = token + if not s: + proxy.ch_y.terminate(IOError("Invalid service name")) + else: + key = proxy.ch_x.sendCommand(s, name, data, cmd_listener_y) + proxy.tokens_y[key] = token + def onEvent(self, service, name, data): s = proxy.ch_y.getRemoteService(service) - if not s: proxy.ch_y.terminate(IOError("Invalid service name")) - elif not proxy.closed_x: proxy.ch_x.sendEvent(s, name, data) + if not s: + proxy.ch_y.terminate(IOError("Invalid service name")) + elif not proxy.closed_x: + proxy.ch_x.sendEvent(s, name, data) proxy_x = ProxyX() proxy_y = ProxyY() try: self.ch_y.setProxy(proxy_y, self.ch_x.getRemoteServices()) + class ChannelListener(channel.ChannelListener): def onChannelClosed(self, error): proxy.ch_y.removeChannelListener(self) - if error is None: error = Exception("Channel closed") + if error is None: + error = Exception("Channel closed") + def onChannelOpened(self): proxy.ch_y.removeChannelListener(self) try: - proxy.ch_x.setProxy(proxy_x, proxy.ch_y.getRemoteServices()) + proxy.ch_x.setProxy(proxy_x, + proxy.ch_y.getRemoteServices()) except IOError as e: proxy.ch_x.terminate(e) proxy.ch_y.terminate(e) diff --git a/python/src/tcf/channel/ChannelTCP.py b/python/src/tcf/channel/ChannelTCP.py index 7126e9554..8f7b19a2c 100644 --- a/python/src/tcf/channel/ChannelTCP.py +++ b/python/src/tcf/channel/ChannelTCP.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,20 +7,25 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +import socket +import types + +from .. import protocol +from .StreamChannel import StreamChannel -import socket, types -from tcf import protocol -from StreamChannel import StreamChannel class ChannelTCP(StreamChannel): - "ChannelTCP is a channel implementation that works on top of TCP sockets as a transport." + """ChannelTCP is a channel implementation that works on top of TCP sockets + as a transport.""" def __init__(self, remote_peer, host, port): super(ChannelTCP, self).__init__(remote_peer) self.closed = False self.started = False channel = self + class CreateSocket(object): def __call__(self): try: @@ -49,15 +54,18 @@ class ChannelTCP(StreamChannel): self.start() def get(self): - if self.closed: return -1 + if self.closed: + return -1 try: return ord(self.socket.recv(1)) except socket.error as x: - if self.closed: return -1 + if self.closed: + return -1 raise x def getBuf(self, buf): - if self.closed: return -1 + if self.closed: + return -1 try: return self.socket.recv_into(buf) except TypeError: @@ -66,11 +74,13 @@ class ChannelTCP(StreamChannel): self.getBuf = super(ChannelTCP, self).getBuf return self.getBuf(buf) except socket.error as x: - if self.closed: return -1 + if self.closed: + return -1 raise x def put(self, b): - if self.closed: return + if self.closed: + return t = type(b) if t is types.StringType: s = b @@ -81,7 +91,8 @@ class ChannelTCP(StreamChannel): self.socket.send(s) def putBuf(self, buf): - if self.closed: return + if self.closed: + return t = type(buf) if t is types.StringType: s = buf diff --git a/python/src/tcf/channel/Command.py b/python/src/tcf/channel/Command.py index 53256f0aa..72b6e9544 100644 --- a/python/src/tcf/channel/Command.py +++ b/python/src/tcf/channel/Command.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,24 +7,26 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import cStringIO -from tcf import protocol, errors, services -from tcf.channel import Token, toJSONSequence, fromJSONSequence, dumpJSONObject +from .. import protocol, errors, services +from ..channel import Token, toJSONSequence, fromJSONSequence, dumpJSONObject + class Command(object): - """ - This is utility class that helps to implement sending a command and receiving - command result over TCF communication channel. The class uses JSON to encode - command arguments and to decode result data. + """This is utility class that helps to implement sending a command and + receiving command result over TCF communication channel. + + The class uses JSON to encode command arguments and to decode result data. The class also provides support for TCF standard error report encoding. - Clients are expected to subclass <code>Command</code> and override <code>done</code> method. + Clients are expected to subclass <code>Command</code> and override + <code>done</code> method. - Note: most clients don't need to handle protocol commands directly and - can use service APIs instead. Service API does all command encoding/decoding + Note: most clients don't need to handle protocol commands directly and can + use service APIs instead. Service API does all command encoding/decoding for a client. Typical usage example: @@ -52,8 +54,9 @@ class Command(object): t = None try: # TODO zero_copy - #zero_copy = channel.isZeroCopySupported() - t = channel.sendCommand(service, command, toJSONSequence(args), self) + # zero_copy = channel.isZeroCopySupported() + t = channel.sendCommand(service, command, toJSONSequence(args), + self) except Exception as y: t = Token() protocol.invokeLater(self._error, y) @@ -90,7 +93,7 @@ class Command(object): def getCommandString(self): buf = cStringIO.StringIO() - buf.write(self.service) + buf.write(str(self.service)) buf.write(" ") buf.write(self.command) if self.args is not None: @@ -110,14 +113,16 @@ class Command(object): return buf.getvalue() def toError(self, data, include_command_text=True): - if not isinstance(data, dict): return None - map = data + if not isinstance(data, dict): + return None + errMap = data bf = cStringIO.StringIO() bf.write("TCF error report:\n") if include_command_text: cmd = self.getCommandString() - if len(cmd) > 120: cmd = cmd[:120] + "..." + if len(cmd) > 120: + cmd = cmd[:120] + "..." bf.write("Command: ") bf.write(cmd) - errors.appendErrorProps(bf, map) - return errors.ErrorReport(bf.getvalue(), map) + errors.appendErrorProps(bf, errMap) + return errors.ErrorReport(bf.getvalue(), errMap) diff --git a/python/src/tcf/channel/StreamChannel.py b/python/src/tcf/channel/StreamChannel.py index 9c6d2239a..ffadca8af 100644 --- a/python/src/tcf/channel/StreamChannel.py +++ b/python/src/tcf/channel/StreamChannel.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,24 +7,29 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import types -from AbstractChannel import AbstractChannel, EOS, EOM +from .AbstractChannel import AbstractChannel, EOS, EOM ESC = 3 + class StreamChannel(AbstractChannel): - """ - Abstract channel implementation for stream oriented transport protocols. + """Abstract channel implementation for stream oriented transport protocols. - StreamChannel implements communication link connecting two end points (peers). - The channel asynchronously transmits messages: commands, results and events. + StreamChannel implements communication link connecting two end points + (peers). + The channel asynchronously transmits messages: commands, results and + events. - StreamChannel uses escape sequences to represent End-Of-Message and End-Of-Stream markers. + StreamChannel uses escape sequences to represent End-Of-Message and + End-Of-Stream markers. - Clients can subclass StreamChannel to support particular stream oriented transport (wire) protocol. - Also, see ChannelTCP for a concrete IChannel implementation that works on top of TCP sockets as a transport. + Clients can subclass StreamChannel to support particular stream oriented + transport (wire) protocol. + Also, see ChannelTCP for a concrete IChannel implementation that works on + top of TCP sockets as a transport. """ def __init__(self, remote_peer, local_peer=None): @@ -36,6 +41,7 @@ class StreamChannel(AbstractChannel): def get(self): pass + def put(self, n): pass @@ -45,49 +51,61 @@ class StreamChannel(AbstractChannel): while i < l: b = self.get() if b < 0: - if i == 0: return -1 + if i == 0: + return -1 break buf[i] = b i += 1 - if i >= self.bin_data_size: break + if i >= self.bin_data_size: + break return i def putBuf(self, buf): - for b in buf: self.put(b & 0xff) + for b in buf: + self.put(b & 0xff) def read(self): while True: while self.buf_pos >= self.buf_len: self.buf_len = self.getBuf(self.buf) self.buf_pos = 0 - if self.buf_len < 0: return EOS + if self.buf_len < 0: + return EOS res = self.buf[self.buf_pos] & 0xff self.buf_pos += 1 if self.bin_data_size > 0: self.bin_data_size -= 1 return res - if res != ESC: return res + if res != ESC: + return res while self.buf_pos >= self.buf_len: self.buf_len = self.getBuf(self.buf) self.buf_pos = 0 - if self.buf_len < 0: return EOS + if self.buf_len < 0: + return EOS n = self.buf[self.buf_pos] & 0xff self.buf_pos += 1 - if n == 0: return ESC - elif n == 1: return EOM - elif n == 2: return EOS + if n == 0: + return ESC + elif n == 1: + return EOM + elif n == 2: + return EOS elif n == 3: for i in xrange(0, 100000, 7): while self.buf_pos >= self.buf_len: self.buf_len = self.getBuf(self.buf) self.buf_pos = 0 - if self.buf_len < 0: return EOS + if self.buf_len < 0: + return EOS m = self.buf[self.buf_pos] & 0xff self.buf_pos += 1 self.bin_data_size |= (m & 0x7f) << i - if (m & 0x80) == 0: break + if (m & 0x80) == 0: + break else: - if n < 0: return EOS + if n < 0: + return EOS assert False def writeByte(self, n): diff --git a/python/src/tcf/channel/__init__.py b/python/src/tcf/channel/__init__.py index 1e89c0bbe..7ac9ccb54 100644 --- a/python/src/tcf/channel/__init__.py +++ b/python/src/tcf/channel/__init__.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,25 +7,30 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** -import cStringIO, json, binascii, types +import binascii +import cStringIO +import json +import types # channel states STATE_OPENING = 0 STATE_OPEN = 1 STATE_CLOSED = 2 + class TraceListener(object): - def onMessageReceived(self, type, token, service, name, data): + def onMessageReceived(self, t, token, service, name, data): pass - def onMessageSent(self, type, token, service, name, data): + def onMessageSent(self, t, token, service, name, data): pass def onChannelClosed(self, error): pass + class Proxy(object): def onCommand(self, token, service, name, data): pass @@ -37,23 +42,29 @@ class Proxy(object): pass _token_cnt = 0 + + class Token(object): - def __init__(self, id=None, listener=None): - if id is None: + def __init__(self, tokenID=None, listener=None): + if tokenID is None: global _token_cnt - id = str(_token_cnt) + tokenID = str(_token_cnt) _token_cnt += 1 else: - id = str(id) - self.id = id + tokenID = str(tokenID) + self.id = tokenID self.listener = listener + def getID(self): return self.id + def getListener(self): return self.listener + def cancel(self): return False + class ChannelListener(object): """ Channel listener interface. @@ -76,12 +87,14 @@ class ChannelListener(object): def congestionLevel(self, level): """ - Notifies listeners about channel out-bound traffic congestion level changes. + Notifies listeners about channel out-bound traffic congestion level + changes. When level > 0 client should delay sending more messages. @param level - current congestion level """ pass + class EventListener(object): """ A generic interface for service event listener. @@ -91,6 +104,7 @@ class EventListener(object): unless no such interface is defined. """ svc_name = "<unknown>" + def event(self, name, data): """ Called when service event message is received @@ -99,6 +113,7 @@ class EventListener(object): """ pass + class CommandServer(object): """ Command server interface. @@ -113,6 +128,7 @@ class CommandServer(object): """ pass + class CommandListener(object): """ Command listener interface. Clients implement this interface to @@ -126,22 +142,26 @@ class CommandListener(object): @param data - progress message arguments encoded into array of bytes """ pass + def result(self, token, data): """ Called when command result received from remote peer. @param token - command handle - @param data - command result message arguments encoded into array of bytes + @param data - command result message arguments encoded into array of + bytes """ pass + def terminated(self, token, error): """ - Called when command is terminated because communication channel was closed or - command is not recognized by remote peer. + Called when command is terminated because communication channel was + closed or command is not recognized by remote peer. @param token - command handle @param error - exception that forced the channel to close """ pass + def toJSONSequence(args): if args is None: return None @@ -151,6 +171,7 @@ def toJSONSequence(args): buf.write('\0') return buf.getvalue() + def fromJSONSequence(byteArray): if byteArray[-1] == 0: del byteArray[-1] @@ -164,19 +185,24 @@ def fromJSONSequence(byteArray): objects.append(None) return objects + def dumpJSONObject(obj, buf): json.dump(obj, buf, separators=(',', ':'), cls=TCFJSONEncoder) + def toByteArray(data): - if data is None: return None + if data is None: + return None t = type(data) - if t is bytearray: return data + if t is bytearray: + return data elif t is str: return binascii.a2b_base64(data) elif t is unicode: return binascii.a2b_base64(str(data)) raise TypeError(str(t)) + class TCFJSONEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, bytearray): diff --git a/python/src/tcf/errors.py b/python/src/tcf/errors.py index 947590167..9085e29b6 100644 --- a/python/src/tcf/errors.py +++ b/python/src/tcf/errors.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,19 +7,21 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** -import cStringIO, time, types +import cStringIO +import time +import types # Error report attribute names -ERROR_CODE = "Code" # integer -ERROR_TIME = "Time" # integer -ERROR_SERVICE = "Service" # string -ERROR_FORMAT = "Format" # string -ERROR_PARAMS = "Params" # array -ERROR_SEVERITY = "Severity" # integer -ERROR_ALT_CODE = "AltCode" # integer -ERROR_ALT_ORG = "AltOrg" # string +ERROR_CODE = "Code" # integer +ERROR_TIME = "Time" # integer +ERROR_SERVICE = "Service" # string +ERROR_FORMAT = "Format" # string +ERROR_PARAMS = "Params" # array +ERROR_SEVERITY = "Severity" # integer +ERROR_ALT_CODE = "AltCode" # integer +ERROR_ALT_ORG = "AltOrg" # string ERROR_CAUSED_BY = "CausedBy" # object # Error severity codes @@ -41,37 +43,38 @@ CODE_RESERVED_MIN = 0x20000 CODE_RESERVED_MAX = 0x2ffff # Standard TCF error codes -TCF_ERROR_OTHER = 1 -TCF_ERROR_JSON_SYNTAX = 2 -TCF_ERROR_PROTOCOL = 3 -TCF_ERROR_BUFFER_OVERFLOW = 4 -TCF_ERROR_CHANNEL_CLOSED = 5 -TCF_ERROR_COMMAND_CANCELLED = 6 -TCF_ERROR_UNKNOWN_PEER = 7 -TCF_ERROR_BASE64 = 8 -TCF_ERROR_EOF = 9 -TCF_ERROR_ALREADY_STOPPED = 10 -TCF_ERROR_ALREADY_EXITED = 11 -TCF_ERROR_ALREADY_RUNNING = 12 -TCF_ERROR_ALREADY_ATTACHED = 13 -TCF_ERROR_IS_RUNNING = 14 -TCF_ERROR_INV_DATA_SIZE = 15 -TCF_ERROR_INV_CONTEXT = 16 -TCF_ERROR_INV_ADDRESS = 17 -TCF_ERROR_INV_EXPRESSION = 18 -TCF_ERROR_INV_FORMAT = 19 -TCF_ERROR_INV_NUMBER = 20 -TCF_ERROR_INV_DWARF = 21 -TCF_ERROR_SYM_NOT_FOUND = 22 -TCF_ERROR_UNSUPPORTED = 23 -TCF_ERROR_INV_DATA_TYPE = 24 -TCF_ERROR_INV_COMMAND = 25 -TCF_ERROR_INV_TRANSPORT = 26 -TCF_ERROR_CACHE_MISS = 27 -TCF_ERROR_NOT_ACTIVE = 28 +TCF_ERROR_OTHER = 1 +TCF_ERROR_JSON_SYNTAX = 2 +TCF_ERROR_PROTOCOL = 3 +TCF_ERROR_BUFFER_OVERFLOW = 4 +TCF_ERROR_CHANNEL_CLOSED = 5 +TCF_ERROR_COMMAND_CANCELLED = 6 +TCF_ERROR_UNKNOWN_PEER = 7 +TCF_ERROR_BASE64 = 8 +TCF_ERROR_EOF = 9 +TCF_ERROR_ALREADY_STOPPED = 10 +TCF_ERROR_ALREADY_EXITED = 11 +TCF_ERROR_ALREADY_RUNNING = 12 +TCF_ERROR_ALREADY_ATTACHED = 13 +TCF_ERROR_IS_RUNNING = 14 +TCF_ERROR_INV_DATA_SIZE = 15 +TCF_ERROR_INV_CONTEXT = 16 +TCF_ERROR_INV_ADDRESS = 17 +TCF_ERROR_INV_EXPRESSION = 18 +TCF_ERROR_INV_FORMAT = 19 +TCF_ERROR_INV_NUMBER = 20 +TCF_ERROR_INV_DWARF = 21 +TCF_ERROR_SYM_NOT_FOUND = 22 +TCF_ERROR_UNSUPPORTED = 23 +TCF_ERROR_INV_DATA_TYPE = 24 +TCF_ERROR_INV_COMMAND = 25 +TCF_ERROR_INV_TRANSPORT = 26 +TCF_ERROR_CACHE_MISS = 27 +TCF_ERROR_NOT_ACTIVE = 28 _timestamp_format = "%Y-%m-%d %H:%M:%S" + class ErrorReport(Exception): def __init__(self, msg, attrs): super(ErrorReport, self).__init__(msg) @@ -85,12 +88,12 @@ class ErrorReport(Exception): self.attrs = attrs caused_by = attrs.get(ERROR_CAUSED_BY) if caused_by: - map = caused_by + errMap = caused_by bf = cStringIO.StringIO() bf.write("TCF error report:") bf.write('\n') - appendErrorProps(bf, map) - self.caused_by = ErrorReport(bf.getvalue(), map) + appendErrorProps(bf, errMap) + self.caused_by = ErrorReport(bf.getvalue(), errMap) def getErrorCode(self): return self.attrs.get(ERROR_CODE) or 0 @@ -106,44 +109,52 @@ class ErrorReport(Exception): def toErrorString(data): - if not data: return None - map = data - fmt = map.get(ERROR_FORMAT) + if not data: + return None + errMap = data + fmt = errMap.get(ERROR_FORMAT) if fmt: - c = map.get(ERROR_PARAMS) - if c: return fmt.format(c) + c = errMap.get(ERROR_PARAMS) + if c: + return fmt.format(c) return fmt - code = map.get(ERROR_CODE) + code = errMap.get(ERROR_CODE) if code is not None: if code == TCF_ERROR_OTHER: - alt_org = map.get(ERROR_ALT_ORG) - alt_code = map.get(ERROR_ALT_CODE) + alt_org = errMap.get(ERROR_ALT_ORG) + alt_code = errMap.get(ERROR_ALT_CODE) if alt_org and alt_code: return "%s Error %d" % (alt_org, alt_code) return "TCF Error %d" % code return "Invalid error report format" -def appendErrorProps(bf, map): - timeVal = map.get(ERROR_TIME) - code = map.get(ERROR_CODE) - service = map.get(ERROR_SERVICE) - severity = map.get(ERROR_SEVERITY) - alt_code = map.get(ERROR_ALT_CODE) - alt_org = map.get(ERROR_ALT_ORG) + +def appendErrorProps(bf, errMap): + timeVal = errMap.get(ERROR_TIME) + code = errMap.get(ERROR_CODE) + service = errMap.get(ERROR_SERVICE) + severity = errMap.get(ERROR_SEVERITY) + alt_code = errMap.get(ERROR_ALT_CODE) + alt_org = errMap.get(ERROR_ALT_ORG) if timeVal: bf.write('\n') bf.write("Time: ") - bf.write(time.strftime(_timestamp_format, time.localtime(timeVal/1000.))) + bf.write(time.strftime(_timestamp_format, + time.localtime(timeVal / 1000.))) if severity: bf.write('\n') bf.write("Severity: ") - if severity == SEVERITY_ERROR: bf.write("Error") - elif severity == SEVERITY_FATAL: bf.write("Fatal") - elif severity == SEVERITY_WARNING: bf.write("Warning") - else: bf.write("Unknown") + if severity == SEVERITY_ERROR: + bf.write("Error") + elif severity == SEVERITY_FATAL: + bf.write("Fatal") + elif severity == SEVERITY_WARNING: + bf.write("Warning") + else: + bf.write("Unknown") bf.write('\n') bf.write("Error text: ") - bf.write(toErrorString(map)) + bf.write(toErrorString(errMap)) bf.write('\n') bf.write("Error code: ") bf.write(str(code)) diff --git a/python/src/tcf/peer.py b/python/src/tcf/peer.py index b96cabd02..03122b1b3 100644 --- a/python/src/tcf/peer.py +++ b/python/src/tcf/peer.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -26,8 +26,8 @@ All peers of particular service manager represent identical sets of services. import os import time -from tcf import protocol, transport, services, channel -from tcf.services import locator +from . import protocol, transport, services, channel +from .services import locator # Peer unique ID ATTR_ID = "ID" diff --git a/python/src/tcf/protocol.py b/python/src/tcf/protocol.py index 1f94ff406..2fd45e634 100644 --- a/python/src/tcf/protocol.py +++ b/python/src/tcf/protocol.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,44 +7,55 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** """ -Module protocol provides static methods to access Target Communication Framework root objects: +Module protocol provides static methods to access Target Communication +Framework root objects: + 1. the framework event queue and dispatch thread -2. local instance of Locator service, which maintains a list of available targets +2. local instance of Locator service, which maintains a list of available + targets 3. list of open communication channels. It also provides utility methods for posting asynchronous events, including delayed events (timers). """ -import sys, uuid, threading, time -from EventQueue import EventQueue +import sys +import threading +import time +import uuid + +from . import EventQueue _event_queue = None _timer_dispatcher = None + def startEventQueue(): global _event_queue, _timer_dispatcher - if _event_queue and not _event_queue.isShutdown(): return - _event_queue = EventQueue(on_shutdown=shutdownDiscovery) + if _event_queue and not _event_queue.isShutdown(): + return + _event_queue = EventQueue.EventQueue(on_shutdown=shutdownDiscovery) _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 = threading.Thread(target=_dispatch_timers) _timer_dispatcher.setName("TCF Timer Dispatcher") _timer_dispatcher.setDaemon(True) _timer_dispatcher.start() + def getEventQueue(): """ @return instance of event queue that is used for TCF events. """ return _event_queue + def isDispatchThread(): """ Returns true if the calling thread is the TCF event dispatch thread. @@ -55,7 +66,8 @@ def isDispatchThread(): """ return _event_queue is not None and _event_queue.isDispatchThread() -def invokeLater(callable, *args, **kwargs): + +def invokeLater(c, *args, **kwargs): """ Causes callable to be called with given arguments in the dispatch thread of the framework. @@ -66,11 +78,12 @@ def invokeLater(callable, *args, **kwargs): This method can be invoked from any thread. - @param callable the callable to be executed asynchronously + @param c - the callable to be executed asynchronously """ - _event_queue.invokeLater(callable, *args, **kwargs) + _event_queue.invokeLater(c, *args, **kwargs) + -def invokeLaterWithDelay(delay, callable, *args, **kwargs): +def invokeLaterWithDelay(delay, c, *args, **kwargs): """ Causes callable event to called in the dispatch thread of the framework. The event is dispatched after given delay. @@ -80,17 +93,19 @@ def invokeLaterWithDelay(delay, callable, *args, **kwargs): @param delay milliseconds to delay event dispatch. If delay <= 0 the event is posted into the "ready" queue without delay. - @param callable the callable to be executed asynchronously. + @param c - the callable to be executed asynchronously. """ if delay <= 0: - _event_queue.invokeLater(callable, *args, **kwargs) + _event_queue.invokeLater(c, *args, **kwargs) else: with _timer_queue_lock: - _timer_queue.append(Timer(time.time() + delay/1000., callable, *args, **kwargs)) + _timer_queue.append(Timer(time.time() + delay / 1000., c, *args, + **kwargs)) _timer_queue.sort() _timer_queue_lock.notify() -def invokeAndWait(callable, *args, **kwargs): + +def invokeAndWait(c, *args, **kwargs): """ Causes callable to be called in the dispatch thread of the framework. Calling thread is suspended until the method is executed. @@ -99,16 +114,17 @@ def invokeAndWait(callable, *args, **kwargs): This method can be invoked from any thread. - @param callable the callable to be executed on dispatch thread. + @param c the callable to be executed on dispatch thread. """ if _event_queue.isDispatchThread(): - return callable(*args, **kwargs) + return c(*args, **kwargs) else: class DoRun(): result = None + def __call__(self): try: - self.result = callable(*args, **kwargs) + self.result = c(*args, **kwargs) finally: with runLock: runLock.notify() @@ -120,10 +136,14 @@ def invokeAndWait(callable, *args, **kwargs): return doRun.result _agentID = str(uuid.uuid4()) + + def getAgentID(): return _agentID _logger = None + + def setLogger(logger): """ Set framework logger. @@ -134,6 +154,7 @@ def setLogger(logger): global _logger _logger = logger + def log(msg, x=None): """ Logs the given message. @@ -143,22 +164,23 @@ def log(msg, x=None): @param x - an exception associated with the log entry or None. """ if not _logger: - print>>sys.stderr, msg + print >> sys.stderr, msg while x: import traceback - print>>sys.stderr, "%s: %s" % (type(x).__name__, x) + print >> sys.stderr, "%s: %s" % (type(x).__name__, x) tb = getattr(x, "tb", None) or sys.exc_info()[2] if tb: traceback.print_tb(tb) caused_by = getattr(x, "caused_by", None) if caused_by: - print>>sys.stderr, "Caused by:" + print >> sys.stderr, "Caused by:" x = caused_by else: break else: _logger.log(msg, x) + def startDiscovery(): "Start discovery of remote peers if not running yet" # initialize LocatorService @@ -166,21 +188,24 @@ def startDiscovery(): if LocatorService.locator: invokeAndWait(LocatorService.startup) + def shutdownDiscovery(): "Shutdown discovery if running" - from tcf.services.local.LocatorService import LocatorService + from .services.local.LocatorService import LocatorService if LocatorService.locator: invokeAndWait(LocatorService.shutdown) - + + def getLocator(): """ Get instance of the framework locator service. The service can be used to discover available remote peers. @return instance of LocatorService. """ - from tcf.services.local.LocatorService import LocatorService + from .services.local.LocatorService import LocatorService return LocatorService.locator + def getOpenChannels(): """ Return an array of all open channels. @@ -190,20 +215,22 @@ def getOpenChannels(): import transport return transport.getOpenChannels() + class ChannelOpenListener(object): """ Interface to be implemented by clients willing to be notified when new TCF communication channel is opened. - The interface allows a client to get pointers to channel objects - that were opened by somebody else. If a client open a channel itself, it already has - the pointer and does not need protocol.ChannelOpenListener. If a channel is created, - for example, by remote peer connecting to the client, the only way to get the pointer - is protocol.ChannelOpenListener. + The interface allows a client to get pointers to channel objects that were + opened by somebody else. If a client open a channel itself, it already has + the pointer and does not need protocol.ChannelOpenListener. If a channel is + created, for example, by remote peer connecting to the client, the only way + to get the pointer is protocol.ChannelOpenListener. """ def onChannelOpen(self, channel): pass + def addChannelOpenListener(listener): """ Add a listener that will be notified when new channel is opened. @@ -213,6 +240,7 @@ def addChannelOpenListener(listener): import transport transport.addChannelOpenListener(listener) + def removeChannelOpenListener(listener): """ Remove channel opening listener. @@ -222,6 +250,7 @@ def removeChannelOpenListener(listener): import transport transport.removeChannelOpenListener(listener) + def sendEvent(service_name, event_name, data): """ Transmit TCF event message. @@ -231,42 +260,54 @@ def sendEvent(service_name, event_name, data): import transport transport.sendEvent(service_name, event_name, data) + def sync(done): """ - Call back after all TCF messages sent by this host up to this moment are delivered - to their intended target. This method is intended for synchronization of messages - across multiple channels. + Call back after all TCF messages sent by this host up to this moment are + delivered to their intended target. This method is intended for + synchronization of messages across multiple channels. Note: Cross channel synchronization can reduce performance and throughput. - Most clients don't need cross channel synchronization and should not call this method. + Most clients don't need cross channel synchronization and should not call + this method. - @param done will be executed by dispatch thread after pending communication - messages are delivered to corresponding targets. + @param done - will be executed by dispatch thread after pending + communication messages are delivered to corresponding + targets. """ assert isDispatchThread() import transport transport.sync(done) + class CongestionMonitor(object): """ - Clients implement CongestionMonitor interface to monitor usage of local resources, - like, for example, display queue size - if the queue becomes too big, UI response time - can become too high, or it can crash all together because of OutOfMemory errors. - TCF flow control logic prevents such conditions by throttling traffic coming from remote peers. - Note: Local (in-bound traffic) congestion is detected by framework and reported to - remote peer without client needed to be involved. Only clients willing to provide - additional data about local congestion should implement CongestionMonitor and - register it using protocol.addCongestionMonitor(). + Clients implement CongestionMonitor interface to monitor usage of local + resources, like, for example, display queue size - if the queue becomes too + big, UI response time can become too high, or it can crash all together + because of OutOfMemory errors. + + TCF flow control logic prevents such conditions by throttling traffic + coming from remote peers. + + Note: Local (in-bound traffic) congestion is detected by framework and + reported to remote peer without client needed to be involved. Only + clients willing to provide additional data about local congestion + should implement CongestionMonitor and register it using + protocol.addCongestionMonitor(). """ def getCongestionLevel(self): """ Get current level of client resource utilization. - @return integer value in range -100..100, where -100 means all resources are free, - 0 means optimal load, and positive numbers indicate level of congestion. + @return integer value in range -100..100, where -100 means all + resources are free, 0 means optimal load, and positive numbers + indicate level of congestion. """ raise NotImplementedError("Abstract method") _congestion_monitors = [] + + def addCongestionMonitor(monitor): """ Register a congestion monitor. @@ -275,6 +316,7 @@ def addCongestionMonitor(monitor): assert isDispatchThread() _congestion_monitors.add(monitor) + def removeCongestionMonitor(monitor): """ Unregister a congestion monitor. @@ -283,6 +325,7 @@ def removeCongestionMonitor(monitor): assert isDispatchThread() _congestion_monitors.remove(monitor) + def getCongestionLevel(): """ Get current level of local traffic congestion. @@ -295,13 +338,17 @@ def getCongestionLevel(): level = -100 for m in _congestion_monitors: n = m.getCongestionLevel() - if n > level: level = n + if n > level: + level = n if _event_queue: n = _event_queue.getCongestion() - if n > level: level = n - if level > 100: level = 100 + if n > level: + level = n + if level > 100: + level = 100 return level + def addServiceProvider(provider): """ Register service provider. @@ -311,6 +358,7 @@ def addServiceProvider(provider): import services services.addServiceProvider(provider) + def removeServiceProvider(provider): """ Unregister service provider. @@ -320,6 +368,7 @@ def removeServiceProvider(provider): import services services.removeServiceProvider(provider) + def addTransportProvider(provider): """ Register transport provider. @@ -329,6 +378,7 @@ def addTransportProvider(provider): import transport transport.addTransportProvider(provider) + def removeTransportProvider(provider): """ Unregister transport provider. @@ -338,8 +388,10 @@ 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 @@ -349,16 +401,23 @@ class Timer(object): 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 + 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: diff --git a/python/src/tcf/services/__init__.py b/python/src/tcf/services/__init__.py index ef65adc4f..f9c87dd52 100644 --- a/python/src/tcf/services/__init__.py +++ b/python/src/tcf/services/__init__.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -11,7 +11,7 @@ import collections import threading -from tcf import protocol +from .. import protocol _providers = [] _lock = threading.RLock() @@ -134,7 +134,7 @@ class DefaultServiceProvider(ServiceProvider): def getLocalService(self, channel): # TODO DiagnosticsService - #return [DiagnosticsService(channel)] + # return [DiagnosticsService(channel)] return [] def getServiceProxy(self, channel, service_name): diff --git a/python/src/tcf/services/breakpoints.py b/python/src/tcf/services/breakpoints.py index b0b2113f5..cdb33000f 100644 --- a/python/src/tcf/services/breakpoints.py +++ b/python/src/tcf/services/breakpoints.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -26,44 +26,44 @@ status reflects dynamic target agent reports about breakpoint current state, like actual addresses where breakpoint is planted or planting errors. """ -from tcf import services +from .. import services # Service name. NAME = "Breakpoints" # Breakpoint property names. -PROP_ID = "ID" # String -PROP_ENABLED = "Enabled" # Boolean -PROP_TYPE = "BreakpointType" # String -PROP_CONTEXT_NAMES = "ContextNames" # Array -PROP_CONTEXT_IDS = "ContextIds" # Array -PROP_EXECUTABLE_PATHS = "ExecPaths" # Array -PROP_CONTEXT_QUERY = "ContextQuery" # String, see IContextQuery -PROP_LOCATION = "Location" # String -PROP_SIZE = "Size" # Number -PROP_ACCESS_MODE = "AccessMode" # Number -PROP_FILE = "File" # String -PROP_LINE = "Line" # Number -PROP_COLUMN = "Column" # Number -PROP_PATTERN = "MaskValue" # Number -PROP_MASK = "Mask" # Number -PROP_STOP_GROUP = "StopGroup" # Array -PROP_IGNORE_COUNT = "IgnoreCount" # Number -PROP_TIME = "Time" # Number -PROP_SCALE = "TimeScale" # String -PROP_UNITS = "TimeUnits" # String -PROP_CONDITION = "Condition" # String -PROP_TEMPORARY = "Temporary" # Boolean -PROP_EVENT_TYPE = "EventType" # String -PROP_EVENT_ARGS = "EventArgs" # String or Object -PROP_CLIENT_DATA = "ClientData" # Object +PROP_ID = "ID" # String +PROP_ENABLED = "Enabled" # Boolean +PROP_TYPE = "BreakpointType" # String +PROP_CONTEXT_NAMES = "ContextNames" # Array +PROP_CONTEXT_IDS = "ContextIds" # Array +PROP_EXECUTABLE_PATHS = "ExecPaths" # Array +PROP_CONTEXT_QUERY = "ContextQuery" # String, see IContextQuery +PROP_LOCATION = "Location" # String +PROP_SIZE = "Size" # Number +PROP_ACCESS_MODE = "AccessMode" # Number +PROP_FILE = "File" # String +PROP_LINE = "Line" # Number +PROP_COLUMN = "Column" # Number +PROP_PATTERN = "MaskValue" # Number +PROP_MASK = "Mask" # Number +PROP_STOP_GROUP = "StopGroup" # Array +PROP_IGNORE_COUNT = "IgnoreCount" # Number +PROP_TIME = "Time" # Number +PROP_SCALE = "TimeScale" # String +PROP_UNITS = "TimeUnits" # String +PROP_CONDITION = "Condition" # String +PROP_TEMPORARY = "Temporary" # Boolean +PROP_EVENT_TYPE = "EventType" # String +PROP_EVENT_ARGS = "EventArgs" # String or Object +PROP_CLIENT_DATA = "ClientData" # Object # Deprecated -PROP_CONTEXTNAMES = "ContextNames" # Array -PROP_CONTEXTIDS = "ContextIds" # Array -PROP_EXECUTABLEPATHS = "ExecPaths" # Array -PROP_ACCESSMODE = "AccessMode" # Number -PROP_IGNORECOUNT = "IgnoreCount" # Number +PROP_CONTEXTNAMES = "ContextNames" # Array +PROP_CONTEXTIDS = "ContextIds" # Array +PROP_EXECUTABLEPATHS = "ExecPaths" # Array +PROP_ACCESSMODE = "AccessMode" # Number +PROP_IGNORECOUNT = "IgnoreCount" # Number # BreakpointType values @@ -88,36 +88,36 @@ TIMEUNIT_INSTRUCTION_COUNT = "InstructionCount" # Breakpoint status field names. STATUS_INSTANCES = "Instances" # Array of Map<String,Object> -STATUS_ERROR = "Error" # String -STATUS_FILE = "File" # String -STATUS_LINE = "Line" # Number -STATUS_COLUMN = "Column" # Number +STATUS_ERROR = "Error" # String +STATUS_FILE = "File" # String +STATUS_LINE = "Line" # Number +STATUS_COLUMN = "Column" # Number # Breakpoint instance field names. -INSTANCE_ERROR = "Error" # String -INSTANCE_CONTEXT = "LocationContext" # String -INSTANCE_ADDRESS = "Address" # Number -INSTANCE_SIZE = "Size" # Number -INSTANCE_TYPE = "BreakpointType" # String +INSTANCE_ERROR = "Error" # String +INSTANCE_CONTEXT = "LocationContext" # String +INSTANCE_ADDRESS = "Address" # Number +INSTANCE_SIZE = "Size" # Number +INSTANCE_TYPE = "BreakpointType" # String INSTANCE_MEMORY_CONTEXT = "MemoryContext" # String -INSTANCE_HIT_COUNT = "HitCount" # Number +INSTANCE_HIT_COUNT = "HitCount" # Number # Breakpoint service capabilities. -CAPABILITY_CONTEXT_ID = "ID" # String -CAPABILITY_HAS_CHILDREN = "HasChildren" # Boolean +CAPABILITY_CONTEXT_ID = "ID" # String +CAPABILITY_HAS_CHILDREN = "HasChildren" # Boolean CAPABILITY_BREAKPOINT_TYPE = "BreakpointType" # Boolean -CAPABILITY_LOCATION = "Location" # Boolean -CAPABILITY_CONDITION = "Condition" # Boolean -CAPABILITY_FILE_LINE = "FileLine" # Boolean -CAPABILITY_FILE_MAPPING = "FileMapping" # Boolean -CAPABILITY_CONTEXT_IDS = "ContextIds" # Boolean -CAPABILITY_CONTEXT_NAMES = "ContextNames" # Boolean -CAPABILITY_CONTEXT_QUERY = "ContextQuery" # Boolean -CAPABILITY_STOP_GROUP = "StopGroup" # Boolean -CAPABILITY_TEMPORARY = "Temporary" # Boolean -CAPABILITY_IGNORE_COUNT = "IgnoreCount" # Boolean -CAPABILITY_ACCESS_MODE = "AccessMode" # Number -CAPABILITY_CLIENT_DATA = "ClientData" # Boolean +CAPABILITY_LOCATION = "Location" # Boolean +CAPABILITY_CONDITION = "Condition" # Boolean +CAPABILITY_FILE_LINE = "FileLine" # Boolean +CAPABILITY_FILE_MAPPING = "FileMapping" # Boolean +CAPABILITY_CONTEXT_IDS = "ContextIds" # Boolean +CAPABILITY_CONTEXT_NAMES = "ContextNames" # Boolean +CAPABILITY_CONTEXT_QUERY = "ContextQuery" # Boolean +CAPABILITY_STOP_GROUP = "StopGroup" # Boolean +CAPABILITY_TEMPORARY = "Temporary" # Boolean +CAPABILITY_IGNORE_COUNT = "IgnoreCount" # Boolean +CAPABILITY_ACCESS_MODE = "AccessMode" # Number +CAPABILITY_CLIENT_DATA = "ClientData" # Boolean # Deprecated diff --git a/python/src/tcf/services/contextquery.py b/python/src/tcf/services/contextquery.py index c93827a0e..5933fe8c5 100644 --- a/python/src/tcf/services/contextquery.py +++ b/python/src/tcf/services/contextquery.py @@ -13,7 +13,7 @@ TCF ContextQuery service interface. """ -from tcf import services +from .. import services # Service name. NAME = "ContextQuery" diff --git a/python/src/tcf/services/diagnostics.py b/python/src/tcf/services/diagnostics.py index ea4e40a7b..1550a09ce 100644 --- a/python/src/tcf/services/diagnostics.py +++ b/python/src/tcf/services/diagnostics.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -15,7 +15,7 @@ If implemented, the service can be used for testing of the peer and communication channel functionality and reliability. """ -from tcf import services +from .. import services NAME = "Diagnostics" diff --git a/python/src/tcf/services/disassembly.py b/python/src/tcf/services/disassembly.py index 6b03340ad..2f489fd1d 100644 --- a/python/src/tcf/services/disassembly.py +++ b/python/src/tcf/services/disassembly.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -13,7 +13,7 @@ TCF Disassembly service interface. """ -from tcf import services +from .. import services NAME = "Disassembly" diff --git a/python/src/tcf/services/expressions.py b/python/src/tcf/services/expressions.py index fdf3a725d..68c727ece 100644 --- a/python/src/tcf/services/expressions.py +++ b/python/src/tcf/services/expressions.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -16,7 +16,7 @@ The service can be used to retrieve or modify values of variables or any data structures in remote target memory. """ -from tcf import services +from .. import services # Service name. NAME = "Expressions" diff --git a/python/src/tcf/services/filesystem.py b/python/src/tcf/services/filesystem.py index bfead0d79..b32855536 100644 --- a/python/src/tcf/services/filesystem.py +++ b/python/src/tcf/services/filesystem.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -69,7 +69,7 @@ splice path name components returned by readdir() together using a slash ('/') as the separator, and that will work as expected. """ -from tcf import services +from .. import services # Service name. NAME = "FileSystem" @@ -171,29 +171,29 @@ class FileAttrs(object): return (self.permissions & S_IFMT) == S_IFDIR # The following flags are defined for the 'permissions' field: -S_IFMT = 0170000 # bitmask for the file type bitfields -S_IFSOCK = 0140000 # socket -S_IFLNK = 0120000 # symbolic link -S_IFREG = 0100000 # regular file -S_IFBLK = 0060000 # block device -S_IFDIR = 0040000 # directory -S_IFCHR = 0020000 # character device -S_IFIFO = 0010000 # fifo -S_ISUID = 0004000 # set UID bit -S_ISGID = 0002000 # set GID bit (see below) -S_ISVTX = 0001000 # sticky bit (see below) -S_IRWXU = 00700 # mask for file owner permissions -S_IRUSR = 00400 # owner has read permission -S_IWUSR = 00200 # owner has write permission -S_IXUSR = 00100 # owner has execute permission -S_IRWXG = 00070 # mask for group permissions -S_IRGRP = 00040 # group has read permission -S_IWGRP = 00020 # group has write permission -S_IXGRP = 00010 # group has execute permission -S_IRWXO = 00007 # mask for permissions for others (not in group) -S_IROTH = 00004 # others have read permission -S_IWOTH = 00002 # others have write permission -S_IXOTH = 00001 # others have execute permission +S_IFMT = 0170000 # bitmask for the file type bitfields +S_IFSOCK = 0140000 # socket +S_IFLNK = 0120000 # symbolic link +S_IFREG = 0100000 # regular file +S_IFBLK = 0060000 # block device +S_IFDIR = 0040000 # directory +S_IFCHR = 0020000 # character device +S_IFIFO = 0010000 # fifo +S_ISUID = 0004000 # set UID bit +S_ISGID = 0002000 # set GID bit (see below) +S_ISVTX = 0001000 # sticky bit (see below) +S_IRWXU = 00700 # mask for file owner permissions +S_IRUSR = 00400 # owner has read permission +S_IWUSR = 00200 # owner has write permission +S_IXUSR = 00100 # owner has execute permission +S_IRWXG = 00070 # mask for group permissions +S_IRGRP = 00040 # group has read permission +S_IWGRP = 00020 # group has write permission +S_IXGRP = 00010 # group has execute permission +S_IRWXO = 00007 # mask for permissions for others (not in group) +S_IROTH = 00004 # others have read permission +S_IWOTH = 00002 # others have write permission +S_IXOTH = 00001 # others have execute permission class DirEntry(object): diff --git a/python/src/tcf/services/linenumbers.py b/python/src/tcf/services/linenumbers.py index 422515baa..9f0011fca 100644 --- a/python/src/tcf/services/linenumbers.py +++ b/python/src/tcf/services/linenumbers.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -14,7 +14,7 @@ Line numbers service associates locations in the source files with the corresponding machine instruction addresses in the executable object. """ -from tcf import services +from .. import services NAME = "LineNumbers" diff --git a/python/src/tcf/services/local/LocatorService.py b/python/src/tcf/services/local/LocatorService.py index dffd3556a..5587d60b8 100644 --- a/python/src/tcf/services/local/LocatorService.py +++ b/python/src/tcf/services/local/LocatorService.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -20,11 +20,11 @@ import threading import time import socket import cStringIO -from tcf.services import locator -from tcf.util import logging -from tcf.channel import fromJSONSequence, toJSONSequence -from tcf.channel.ChannelProxy import ChannelProxy -from tcf import protocol, services, channel, peer, errors +from .. import locator +from ...util import logging +from ...channel import fromJSONSequence, toJSONSequence +from ...channel.ChannelProxy import ChannelProxy +from ... import protocol, services, channel, peer, errors # Flag indicating whether tracing of the the discovery activity is enabled. __TRACE_DISCOVERY__ = False @@ -38,10 +38,12 @@ class SubNet(object): self.last_slaves_req_time = 0 def contains(self, addr): - if addr is None or self.address is None: return False + if addr is None or self.address is None: + return False a1 = addr.getAddress() a2 = self.address.getAddress() - if len(a1) != len(a2): return False + if len(a1) != len(a2): + return False i = 0 if self.prefix_length <= len(a1) * 8: l = self.prefix_length @@ -49,87 +51,112 @@ class SubNet(object): l = len(a1) * 8 while i + 8 <= l: n = i / 8 - if a1[n] != a2[n]: return False + if a1[n] != a2[n]: + return False i += 8 while i < l: n = i / 8 m = 1 << (7 - i % 8) - if (a1[n] & m) != (a2[n] & m): return False + if (a1[n] & m) != (a2[n] & m): + return False i += 1 return True + def __eq__(self, o): - if not isinstance(o, SubNet): return False + if not isinstance(o, SubNet): + return False return self.prefix_length == o.prefix_length and \ self.broadcast == o.broadcast and \ self.address == o.address + def __hash__(self): return hash(self.address) + def __str__(self): return "%s/%d" % (self.address.getHostAddress(), self.prefix_length) + class Slave(object): # Time of last packet receiver from self slave last_packet_time = 0 - #Time of last REQ_SLAVES packet received from self slave + # Time of last REQ_SLAVES packet received from self slave last_req_slaves_time = 0 def __init__(self, address, port): self.address = address self.port = port + def __str__(self): return "%s/%d" % (self.address.getHostAddress(), self.port) + class AddressCacheItem(object): address = None time_stamp = 0 used = False + def __init__(self, host): self.host = host + class InetAddress(object): "Mimicking Java InetAddress class" def __init__(self, host, addr): self.host = host self.addr = addr + def getAddress(self): return socket.inet_aton(self.addr) + def getHostAddress(self): return self.addr + def __eq__(self, other): - if not isinstance(other, InetAddress): return False + if not isinstance(other, InetAddress): + return False return self.addr == other.addr + def __str__(self): return "%s/%s" % (self.host or "", self.addr) + class InputPacket(object): "Wrapper for UDP packet data." def __init__(self, data, addr, port): self.data = data self.addr = addr self.port = port + def getLength(self): return len(self.data) + def getData(self): return self.data + def getPort(self): return self.port + def getAddress(self): return self.addr + def __str__(self): - return "[address=%s,port=%d,data=\"%s\"]" % (self.getAddress(), self.getPort(), self.data) + return "[address=%s,port=%d,data=\"%s\"]" % \ + (self.getAddress(), self.getPort(), self.data) DISCOVEY_PORT = 1534 MAX_PACKET_SIZE = 9000 - 40 - 8 PREF_PACKET_SIZE = 1500 - 40 - 8 # TODO: research usage of DNS-SD (DNS Service Discovery) to discover TCF peers + + class LocatorService(locator.LocatorService): locator = None - peers = {} # str->Peer - listeners = [] # list of LocatorListener - error_log = set() # set of str + peers = {} # str->Peer + listeners = [] # list of LocatorListener + error_log = set() # set of str addr_list = [] - addr_cache = {} # str->AddressCacheItem + addr_cache = {} # str->AddressCacheItem addr_request = False local_peer = None last_master_packet_time = 0 @@ -159,7 +186,8 @@ class LocatorService(locator.LocatorService): LocatorService.local_peer = peer.LocalPeer() def _startup(self): - if self._alive: return + if self._alive: + return self._alive = True self._addr_cache_lock = threading.Condition() self.subnets = set() @@ -167,10 +195,12 @@ class LocatorService(locator.LocatorService): self.inp_buf = bytearray(MAX_PACKET_SIZE) self.out_buf = bytearray(MAX_PACKET_SIZE) service = self + class TimerThread(threading.Thread): def __init__(self, _callable): self._callable = _callable super(TimerThread, self).__init__() + def run(self): while service._alive: try: @@ -180,21 +210,25 @@ class LocatorService(locator.LocatorService): # TCF event dispatch is shut down return except Exception as x: - service._log("Unhandled exception in TCF discovery timer thread", x) + service._log("Unhandled exception in TCF discovery " + + "timer thread", x) self.timer_thread = TimerThread(self.__refresh_timer) + class DNSLookupThread(threading.Thread): def run(self): while service._alive: try: itemSet = None with service._addr_cache_lock: + period = locator.DATA_RETENTION_PERIOD if not LocatorService.addr_request: - service._addr_cache_lock.wait(locator.DATA_RETENTION_PERIOD) + service._addr_cache_lock.wait(period) msec = int(time.time() * 1000) for host, a in LocatorService.addr_cache.items(): - if a.time_stamp + locator.DATA_RETENTION_PERIOD * 10 < msec: + if a.time_stamp + period * 10 < msec: if a.used: - if itemSet is None: itemSet = set() + if itemSet is None: + itemSet = set() itemSet.add(a) else: del LocatorService.addr_cache[host] @@ -214,32 +248,40 @@ class LocatorService(locator.LocatorService): a.time_stamp = msec a.used = False except Exception as x: - service._log("Unhandled exception in TCF discovery DNS lookup thread", x) + service._log("Unhandled exception in TCF discovery " + + "DNS lookup thread", x) self.dns_lookup_thread = DNSLookupThread() + class InputThread(threading.Thread): def __init__(self, _callable): self._callable = _callable super(InputThread, self).__init__() + def run(self): try: while service._alive: sock = service.socket try: data, addr = sock.recvfrom(MAX_PACKET_SIZE) - p = InputPacket(data, InetAddress(None, addr[0]), addr[1]) + p = InputPacket(data, InetAddress(None, addr[0]), + addr[1]) protocol.invokeAndWait(self._callable, p) except RuntimeError: # TCF event dispatch is shutdown return except socket.error as x: - if sock != service.socket: continue + if sock != service.socket: + continue # frequent error on windows, unknown reason - if x.errno == 10054: continue + if x.errno == 10054: + continue port = sock.getsockname()[1] - service._log("Cannot read from datagram socket at port %d" % port, x) + service._log("Cannot read from datagram socket " + + "at port %d" % port, x) time.sleep(2) except Exception as x: - service._log("Unhandled exception in socket reading thread", x) + service._log("Unhandled exception in socket reading " + + "thread", x) self.input_thread = InputThread(self.__handleDatagramPacket) try: self.loopback_addr = InetAddress(None, "127.0.0.1") @@ -248,11 +290,13 @@ class LocatorService(locator.LocatorService): try: self.socket.bind(('', DISCOVEY_PORT)) if __TRACE_DISCOVERY__: - logging.trace("Became the master agent (bound to port %d)" % self.socket.getsockname()[1]) + logging.trace("Became the master agent (bound to port " + + "%d)" % self.socket.getsockname()[1]) except socket.error as x: self.socket.bind(('', 0)) if __TRACE_DISCOVERY__: - logging.trace("Became a slave agent (bound to port %d)" % self.socket.getsockname()[1]) + logging.trace("Became a slave agent (bound to port " + + "%d)" % self.socket.getsockname()[1]) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.input_thread.setName("TCF Locator Receiver") self.timer_thread.setName("TCF Locator Timer") @@ -263,11 +307,14 @@ class LocatorService(locator.LocatorService): self.input_thread.start() self.timer_thread.start() self.dns_lookup_thread.start() + class LocatorListener(locator.LocatorListener): def peerAdded(self, peer): service._sendPeerInfo(peer, None, 0) + def peerChanged(self, peer): service._sendPeerInfo(peer, None, 0) + self.listeners.append(LocatorListener()) self.__refreshSubNetList() self.__sendPeersRequest(None, 0) @@ -292,12 +339,15 @@ class LocatorService(locator.LocatorService): peer_id = fromJSONSequence(data)[0] _peer = self.peers.get(peer_id) if _peer is None: - error = self.__makeErrorReport(errors.TCF_ERROR_UNKNOWN_PEER, "Unknown peer ID") + errNum = errors.TCF_ERROR_UNKNOWN_PEER + error = self.__makeErrorReport(errNum, "Unknown peer ID") channel.sendResult(token, toJSONSequence((error,))) return channel.sendResult(token, toJSONSequence((None,))) if isinstance(_peer, peer.LocalPeer): - channel.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((channel.getLocalServices(),))) + seq = (channel.getLocalServices(),) + channel.sendEvent(protocol.getLocator(), "Hello", + toJSONSequence(seq)) return ChannelProxy(channel, _peer.openChannel()) elif name == "sync": @@ -313,15 +363,19 @@ class LocatorService(locator.LocatorService): channel.terminate(x) def _log(self, msg, x): - if not self._alive: return - # Don't report same error multiple times to avoid filling up the log file. + if not self._alive: + return + # Don't report same error multiple times to avoid filling up the log + # file. with self._error_log_lock: - if msg in self.error_log: return + if msg in self.error_log: + return self.error_log.add(msg) protocol.log(msg, x) def __getInetAddress(self, host): - if not host: return None + if not host: + return None with self._addr_cache_lock: i = self.addr_cache.get(host) if i is None: @@ -335,7 +389,8 @@ class LocatorService(locator.LocatorService): pass i.time_stamp = int(time.time() * 1000) else: - # socket.gethostbyname() can cause long delay - delegate to background thread + # socket.gethostbyname() can cause long delay - delegate to + # background thread LocatorService.addr_request = True self._addr_cache_lock.notify() self.addr_cache[host] = i @@ -359,15 +414,18 @@ class LocatorService(locator.LocatorService): for p in self.peers.values(): if isinstance(p, peer.RemotePeer): if p.getLastUpdateTime() + locator.DATA_RETENTION_PERIOD < tm: - if stale_peers == None: stale_peers = [] + if stale_peers == None: + stale_peers = [] stale_peers.append(p) if stale_peers is not None: - for p in stale_peers: p.dispose() + for p in stale_peers: + p.dispose() # Try to become a master port = self.socket.getsockname()[1] + period = locator.DATA_RETENTION_PERIOD / 2 if port != DISCOVEY_PORT and \ - self.last_master_packet_time + locator.DATA_RETENTION_PERIOD / 2 <= tm: + self.last_master_packet_time + period <= tm: s0 = self.socket s1 = None try: @@ -387,7 +445,8 @@ class LocatorService(locator.LocatorService): def __addSlave(self, addr, port, timestamp, time_now): for s in self.slaves: if s.port == port and s.address == addr: - if s.last_packet_time < timestamp: s.last_packet_time = timestamp + if s.last_packet_time < timestamp: + s.last_packet_time = timestamp return s s = Slave(addr, port) s.last_packet_time = timestamp @@ -404,16 +463,19 @@ class LocatorService(locator.LocatorService): except Exception as x: self._log("Cannot get list of network interfaces", x) for s in tuple(self.subnets): - if s in subNetSet: continue + if s in subNetSet: + continue self.subnets.remove(s) for s in subNetSet: - if s in self.subnets: continue + if s in self.subnets: + continue self.subnets.add(s) if __TRACE_DISCOVERY__: buf = cStringIO.StringIO() buf.write("Refreshed subnet list:") for subnet in self.subnets: - buf.write("\n\t* address=%s, broadcast=%s" % (subnet.address, subnet.broadcast)) + buf.write("\n\t* address=%s, broadcast=%s" % \ + (subnet.address, subnet.broadcast)) logging.trace(buf.getvalue()) def __getAllIpAddresses (self) : @@ -427,7 +489,7 @@ class LocatorService(locator.LocatorService): ifcfg = struct.unpack \ ( 'iL', - fcntl.ioctl (s.fileno(), 0x8912, # @UndefinedVariable + fcntl.ioctl (s.fileno(), 0x8912, # @UndefinedVariable struct.pack ('iL', nBytes, names.buffer_info ()[0])) )[0] @@ -475,7 +537,8 @@ class LocatorService(locator.LocatorService): for address in self.addr_list: rawaddr = socket.inet_aton(address) - if len(rawaddr) != 4: continue + if len(rawaddr) != 4: + continue rawaddr = rawaddr[:3] + '\xFF' broadcast = socket.inet_ntoa(rawaddr) _set.add(SubNet(24, InetAddress(hostname, address), @@ -500,10 +563,16 @@ class LocatorService(locator.LocatorService): addr = subnet.broadcast port = DISCOVEY_PORT for slave in self.slaves: - self.__sendDatagramPacket(subnet, size, slave.address, slave.port) - if not subnet.contains(addr): return False - if port == self.socket.getsockname()[1] and addr == subnet.address: return False - self.socket.sendto(str(self.out_buf[:size]), (addr.getHostAddress(), port)) + self.__sendDatagramPacket(subnet, size, slave.address, + slave.port) + if not subnet.contains(addr): + return False + if port == self.socket.getsockname()[1] and \ + addr == subnet.address: + return False + + self.socket.sendto(str(self.out_buf[:size]), + (addr.getHostAddress(), port)) if __TRACE_DISCOVERY__: attrs = None @@ -513,7 +582,9 @@ class LocatorService(locator.LocatorService): attrs = self.__parseIDs(self.out_buf, size) elif self.out_buf[4] == locator.CONF_PEERS_REMOVED: attrs = self.__parseIDs(self.out_buf, size) - self.__traceDiscoveryPacket(False, self.packetTypes[self.out_buf[4]], attrs, addr, port) + self.__traceDiscoveryPacket(False, + self.packetTypes[self.out_buf[4]], + attrs, addr, port) except Exception as x: self._log("Cannot send datagram packet to %s" % addr, x) return False @@ -534,13 +605,17 @@ class LocatorService(locator.LocatorService): i = 0 while i < l: i0 = i - while i < l and s[i] != '=' and s[i] != '\0': i += 1 + while i < l and s[i] != '=' and s[i] != '\0': + i += 1 i1 = i - if i < l and s[i] == '=': i += 1 + if i < l and s[i] == '=': + i += 1 i2 = i - while i < l and s[i] != '\0': i += 1 + while i < l and s[i] != '\0': + i += 1 i3 = i - if i < l and s[i] == '\0': i += 1 + if i < l and s[i] == '\0': + i += 1 key = s[i0:i1] val = s[i2:i3] attrs[key] = val @@ -548,8 +623,9 @@ class LocatorService(locator.LocatorService): def __parseIDs(self, data, size): """ - Parse list of IDs in CONF_SLAVES_INFO and CONF_PEERS_REMOVED packet data. - + Parse list of IDs in CONF_SLAVES_INFO and CONF_PEERS_REMOVED packet + data. + @param data - the packet data @param size - the packet size @return a map containing the IDs @@ -561,12 +637,14 @@ class LocatorService(locator.LocatorService): i = 0 while i < l: i0 = i - while i < l and s[i] != '\0': i += 1 + while i < l and s[i] != '\0': + i += 1 if i > i0: _id = s[i0:i] attrs[str(cnt)] = _id cnt += 1 - while i < l and s[i] == '\0': i += 1 + while i < l and s[i] == '\0': + i += 1 return attrs def __sendPeersRequest(self, addr, port): @@ -577,17 +655,23 @@ class LocatorService(locator.LocatorService): def _sendPeerInfo(self, _peer, addr, port): attrs = _peer.getAttributes() peer_addr = self.__getInetAddress(attrs.get(peer.ATTR_IP_HOST)) - if peer_addr is None: return - if attrs.get(peer.ATTR_IP_PORT) is None: return + if peer_addr is None: + return + if attrs.get(peer.ATTR_IP_PORT) is None: + return self.out_buf[4] = locator.CONF_PEER_INFO i = 8 for subnet in self.subnets: if isinstance(_peer, peer.RemotePeer): - if self.socket.getsockname()[1] != DISCOVEY_PORT: return - if not subnet.address == self.loopback_addr and not subnet.address == peer_addr: continue + if self.socket.getsockname()[1] != DISCOVEY_PORT: + return + if not subnet.address == self.loopback_addr and \ + not subnet.address == peer_addr: + continue if not subnet.address == self.loopback_addr: - if not subnet.contains(peer_addr): continue + if not subnet.contains(peer_addr): + continue if i == 8: sb = cStringIO.StringIO() for key in attrs.keys(): @@ -596,21 +680,27 @@ class LocatorService(locator.LocatorService): sb.write(attrs.get(key)) sb.write('\0') bt = self.__getUTF8Bytes(sb.getvalue()) - if i + len(bt) > len(self.out_buf): return + if i + len(bt) > len(self.out_buf): + return self.out_buf[i:i + len(bt)] = bt i += len(bt) - if self.__sendDatagramPacket(subnet, i, addr, port): subnet.send_all_ok = True + if self.__sendDatagramPacket(subnet, i, addr, port): + subnet.send_all_ok = True def __sendEmptyPacket(self, addr, port): self.out_buf[4] = locator.CONF_SLAVES_INFO for subnet in self.subnets: - if subnet.send_all_ok: continue + if subnet.send_all_ok: + continue self.__sendDatagramPacket(subnet, 8, addr, port) def __sendAll(self, addr, port, sl, tm): - for subnet in self.subnets: subnet.send_all_ok = False - for peer in self.peers.values(): self._sendPeerInfo(peer, addr, port) - if addr is not None and sl is not None and sl.last_req_slaves_time + locator.DATA_RETENTION_PERIOD >= tm: + for subnet in self.subnets: + subnet.send_all_ok = False + for peer in self.peers.values(): + self._sendPeerInfo(peer, addr, port) + if addr is not None and sl is not None and \ + sl.last_req_slaves_time + locator.DATA_RETENTION_PERIOD >= tm: self.__sendSlavesInfo(addr, port, tm) self.__sendEmptyPacket(addr, port) @@ -620,10 +710,12 @@ class LocatorService(locator.LocatorService): def __sendSlaveInfo(self, x, tm): ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm - if ttl <= 0: return + if ttl <= 0: + return self.out_buf[4] = locator.CONF_SLAVES_INFO for subnet in self.subnets: - if not subnet.contains(x.address): continue + if not subnet.contains(x.address): + continue i = 8 s = "%d:%s:%s" % (ttl, x.port, x.address.getHostAddress()) bt = self.__getUTF8Bytes(s) @@ -632,23 +724,30 @@ class LocatorService(locator.LocatorService): self.out_buf[i] = 0 i += 1 for y in self.slaves: - if not subnet.contains(y.address): continue - if y.last_req_slaves_time + locator.DATA_RETENTION_PERIOD < tm: continue + if not subnet.contains(y.address): + continue + if y.last_req_slaves_time + locator.DATA_RETENTION_PERIOD < tm: + continue self.__sendDatagramPacket(subnet, i, y.address, y.port) def __sendSlavesInfo(self, addr, port, tm): self.out_buf[4] = locator.CONF_SLAVES_INFO for subnet in self.subnets: - if not subnet.contains(addr): continue + if not subnet.contains(addr): + continue i = 8 for x in self.slaves: ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm - if ttl <= 0: return - if x.port == port and x.address == addr: continue + if ttl <= 0: + return + if x.port == port and x.address == addr: + continue if not subnet.address == self.loopback_addr: - if not subnet.contains(x.address): continue + if not subnet.contains(x.address): + continue subnet.send_all_ok = True - s = "%d:%s:%s" % (x.last_packet_time, x.port, x.address.getHostAddress()) + s = "%d:%s:%s" % \ + (x.last_packet_time, x.port, x.address.getHostAddress()) bt = self.__getUTF8Bytes(s) if i > 8 and i + len(bt) >= PREF_PACKET_SIZE: self.__sendDatagramPacket(subnet, i, addr, port) @@ -657,12 +756,15 @@ class LocatorService(locator.LocatorService): i += len(bt) self.out_buf[i] = 0 i += 1 - if i > 8: self.__sendDatagramPacket(subnet, i, addr, port) + if i > 8: + self.__sendDatagramPacket(subnet, i, addr, port) def __isRemote(self, address, port): - if port != self.socket.getsockname()[1]: return True + if port != self.socket.getsockname()[1]: + return True for s in self.subnets: - if s.address == address: return False + if s.address == address: + return False return True def __handleDatagramPacket(self, p): @@ -670,11 +772,16 @@ class LocatorService(locator.LocatorService): tm = int(time.time() * 1000) buf = p.getData() length = p.getLength() - if length < 8: return - if buf[0] != 'T': return - if buf[1] != 'C': return - if buf[2] != 'F': return - if buf[3] != locator.CONF_VERSION: return + if length < 8: + return + if buf[0] != 'T': + return + if buf[1] != 'C': + return + if buf[2] != 'F': + return + if buf[3] != locator.CONF_VERSION: + return remote_port = p.getPort() remote_address = p.getAddress() if self.__isRemote(remote_address, remote_port): @@ -683,7 +790,8 @@ class LocatorService(locator.LocatorService): else: sl = None if remote_port != DISCOVEY_PORT: - sl = self.__addSlave(remote_address, remote_port, tm, tm) + sl = self.__addSlave(remote_address, remote_port, tm, + tm) code = ord(buf[4]) if code == locator.CONF_PEER_INFO: self.__handlePeerInfoPacket(p) @@ -694,24 +802,32 @@ class LocatorService(locator.LocatorService): elif code == locator.CONF_REQ_SLAVES: self.__handleReqSlavesPacket(p, sl, tm) for subnet in self.subnets: - if not subnet.contains(remote_address): continue + if not subnet.contains(remote_address): + continue delay = locator.DATA_RETENTION_PERIOD / 3 - if remote_port != DISCOVEY_PORT: delay = locator.DATA_RETENTION_PERIOD / 32 - elif subnet.address != remote_address: delay = locator.DATA_RETENTION_PERIOD / 2 + if remote_port != DISCOVEY_PORT: + delay = locator.DATA_RETENTION_PERIOD / 32 + elif subnet.address != remote_address: + delay = locator.DATA_RETENTION_PERIOD / 2 if subnet.last_slaves_req_time + delay <= tm: - self.__sendSlavesRequest(subnet, remote_address, remote_port) + self.__sendSlavesRequest(subnet, remote_address, + remote_port) subnet.last_slaves_req_time = tm - if subnet.address == remote_address and remote_port == DISCOVEY_PORT: + if subnet.address == remote_address and \ + remote_port == DISCOVEY_PORT: self.last_master_packet_time = tm except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) + self._log("Invalid datagram packet received from %s/%s" % \ + (p.getAddress(), p.getPort()), x) def __handlePeerInfoPacket(self, p): try: attrs = self.__parsePeerAttributes(p.getData(), p.getLength()) - if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEER_INFO", attrs, p) + if __TRACE_DISCOVERY__: + self.__traceDiscoveryPacket(True, "CONF_PEER_INFO", attrs, p) _id = attrs.get(peer.ATTR_ID) - if _id is None: raise RuntimeError("Invalid peer info: no ID") + if _id is None: + raise RuntimeError("Invalid peer info: no ID") ok = True host = attrs.get(peer.ATTR_IP_HOST) if host is not None: @@ -729,7 +845,8 @@ class LocatorService(locator.LocatorService): elif _peer is None: peer.RemotePeer(attrs) except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) + self._log("Invalid datagram packet received from %s/%s" % \ + (p.getAddress(), p.getPort()), x) def __handleReqInfoPacket(self, p, sl, tm): if __TRACE_DISCOVERY__: @@ -739,20 +856,26 @@ class LocatorService(locator.LocatorService): def __handleSlavesInfoPacket(self, p, time_now): try: attrs = self.__parseIDs(p.getData(), p.getLength()) - if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_SLAVES_INFO", attrs, p) + if __TRACE_DISCOVERY__: + self.__traceDiscoveryPacket(True, "CONF_SLAVES_INFO", attrs, p) for s in attrs.values(): i = 0 l = len(s) time0 = i - while i < l and s[i] != ':' and s[i] != '\0': i += 1 + while i < l and s[i] != ':' and s[i] != '\0': + i += 1 time1 = i - if i < l and s[i] == ':': i += 1 + if i < l and s[i] == ':': + i += 1 port0 = i - while i < l and s[i] != ':' and s[i] != '\0': i += 1 + while i < l and s[i] != ':' and s[i] != '\0': + i += 1 port1 = i - if i < l and s[i] == ':': i += 1 + if i < l and s[i] == ':': + i += 1 host0 = i - while i < l and s[i] != '\0': i += 1 + while i < l and s[i] != '\0': + i += 1 host1 = i port = int(s[port0:port1]) timestamp = s[time0:time1] @@ -760,44 +883,60 @@ class LocatorService(locator.LocatorService): if port != DISCOVEY_PORT: addr = self.__getInetAddress(host) if addr is not None: - delta = 10006030 # 30 minutes + delta = 10006030 # 30 minutes if len(timestamp) > 0: time_val = int(timestamp) else: time_val = time_now if time_val < 3600000: # Time stamp is "time to live" in milliseconds - time_val = time_now + time_val / 1000 - locator.DATA_RETENTION_PERIOD + time_val = time_now + time_val / 1000 - \ + locator.DATA_RETENTION_PERIOD elif time_val < time_now / 1000 + 50000000: # Time stamp is in seconds time_val = 1000 else: # Time stamp is in milliseconds pass - if time_val < time_now - delta or time_val > time_now + delta: + if time_val < time_now - delta or \ + time_val > time_now + delta: msg = "Invalid slave info timestamp: %s -> %s" % ( - timestamp, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time_val / 1000.))) - self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), Exception(msg)) - time_val = time_now - locator.DATA_RETENTION_PERIOD / 2 + timestamp, + time.strftime("%Y-%m-%d %H:%M:%S", + time.localtime(time_val / + 1000.))) + + self._log("Invalid datagram packet received " + + "from %s/%s" % ( + p.getAddress(), p.getPort()), + Exception(msg)) + time_val = time_now - \ + locator.DATA_RETENTION_PERIOD / 2 self.__addSlave(addr, port, time_val, time_now) except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) + self._log("Invalid datagram packet received from " + + "%s/%s" % (p.getAddress(), p.getPort()), x) def __handleReqSlavesPacket(self, p, sl, tm): - if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_REQ_SLAVES", None, p) - if sl is not None: sl.last_req_slaves_time = tm + if __TRACE_DISCOVERY__: + self.__traceDiscoveryPacket(True, "CONF_REQ_SLAVES", None, p) + if sl is not None: + sl.last_req_slaves_time = tm self.__sendSlavesInfo(p.getAddress(), p.getPort(), tm) def __handlePeerRemovedPacket(self, p): try: attrs = self.__parseIDs(p.getData(), p.getLength()) - if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEERS_REMOVED", attrs, p) + if __TRACE_DISCOVERY__: + self.__traceDiscoveryPacket(True, "CONF_PEERS_REMOVED", attrs, + p) for _id in attrs.values(): _peer = self.peers.get(_id) - if isinstance(_peer, peer.RemotePeer): _peer.dispose() + if isinstance(_peer, peer.RemotePeer): + _peer.dispose() except Exception as x: - self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x) - + self._log("Invalid datagram packet received from %s/%s" % ( + p.getAddress(), p.getPort()), x) @classmethod def getLocator(cls): @@ -823,19 +962,21 @@ class LocatorService(locator.LocatorService): self.listeners.remove(listener) @classmethod - def __traceDiscoveryPacket(cls, received, packet_type, attrs, addr, port=None): + def __traceDiscoveryPacket(cls, received, packet_type, attrs, addr, + port=None): """ Log that a TCF Discovery packet has be sent or received. The trace is - sent to stdout. This should be called only if the tracing has been turned - on. + sent to stdout. This should be called only if the tracing has been + turned on. @param received True if the packet was sent, otherwise it was received @param packet_type - a string specifying the type of packet, e.g., "CONF_PEER_INFO" + a string specifying the type of packet, e.g., + "CONF_PEER_INFO" @param attrs - a set of attributes relevant to the type of packet (typically - a peer's attributes) + a set of attributes relevant to the type of packet + (typically a peer's attributes) @param addr the network address the packet is being sent to @param port @@ -855,6 +996,7 @@ class LocatorService(locator.LocatorService): buf.write("\n\t%s=%s" % (key, value)) logging.trace(buf.getvalue()) + class LocatorServiceProvider(services.ServiceProvider): def getLocalService(self, _channel): class CommandServer(channel.CommandServer): diff --git a/python/src/tcf/services/local/__init__.py b/python/src/tcf/services/local/__init__.py index 29aa42bc1..e1c830ba1 100644 --- a/python/src/tcf/services/local/__init__.py +++ b/python/src/tcf/services/local/__init__.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,4 +7,4 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** diff --git a/python/src/tcf/services/locator.py b/python/src/tcf/services/locator.py index c5c9d9770..424fe6605 100644 --- a/python/src/tcf/services/locator.py +++ b/python/src/tcf/services/locator.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -22,7 +22,7 @@ then locator.getPeers() can be used to get list of available peers (hosts and targets). """ -from tcf import services +from .. import services # Peer data retention period in milliseconds. DATA_RETENTION_PERIOD = 60 * 1000 diff --git a/python/src/tcf/services/memory.py b/python/src/tcf/services/memory.py index 2bdc4fc74..f6f8aa640 100644 --- a/python/src/tcf/services/memory.py +++ b/python/src/tcf/services/memory.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -13,7 +13,7 @@ Memory service provides basic operations to read/write memory on a target. """ -from tcf import services +from .. import services NAME = "Memory" diff --git a/python/src/tcf/services/memorymap.py b/python/src/tcf/services/memorymap.py index b8cca9e28..de5e72b19 100644 --- a/python/src/tcf/services/memorymap.py +++ b/python/src/tcf/services/memorymap.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -14,7 +14,7 @@ MemoryMap service provides information about executable modules (files) mapped (loaded) into target memory. """ -from tcf import services +from .. import services NAME = "MemoryMap" diff --git a/python/src/tcf/services/pathmap.py b/python/src/tcf/services/pathmap.py index ed96042e7..19d4349e4 100644 --- a/python/src/tcf/services/pathmap.py +++ b/python/src/tcf/services/pathmap.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -13,7 +13,7 @@ PathMap service manages file path translation across systems. """ -from tcf import services +from .. import services NAME = "PathMap" diff --git a/python/src/tcf/services/processes.py b/python/src/tcf/services/processes.py index 2e990ee49..6ccf86095 100644 --- a/python/src/tcf/services/processes.py +++ b/python/src/tcf/services/processes.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -21,7 +21,7 @@ available for client to read/write using Streams service. Stream type of such streams is set to "Processes". """ -from tcf import services +from .. import services NAME = "Processes" @@ -57,7 +57,7 @@ PROP_STDERR_ID = "StdErrID" # Number, bit position in the signal mask SIG_INDEX = "Index" -#String, signal name, for example "SIGHUP" +# String, signal name, for example "SIGHUP" SIG_NAME = "Name" # Number, signal code, as defined by OS diff --git a/python/src/tcf/services/registers.py b/python/src/tcf/services/registers.py index e9ab679d5..e18f87833 100644 --- a/python/src/tcf/services/registers.py +++ b/python/src/tcf/services/registers.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -13,7 +13,7 @@ Registers service provides access to target CPU register values and properties. """ -from tcf import services +from .. import services NAME = "Registers" diff --git a/python/src/tcf/services/remote/BreakpointsProxy.py b/python/src/tcf/services/remote/BreakpointsProxy.py index b7674a3b7..c10ea3c9e 100644 --- a/python/src/tcf/services/remote/BreakpointsProxy.py +++ b/python/src/tcf/services/remote/BreakpointsProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,16 +7,18 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import breakpoints +from ... import channel +from ...channel.Command import Command -from tcf import channel -from tcf.services import breakpoints -from tcf.channel.Command import Command class BPCommand(Command): def __init__(self, service, cmd, cb, *args): super(BPCommand, self).__init__(service.channel, service, cmd, args) self.__cb = cb + def done(self, error, args): if not error: assert len(args) == 1 @@ -28,6 +30,7 @@ class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -44,10 +47,11 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 1 self.listener.contextRemoved(args[0]) else: - raise IOError("Breakpoints service: unknown event: " + name); + raise IOError("Breakpoints service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) + class BreakpointsProxy(breakpoints.BreakpointsService): def __init__(self, channel): self.channel = channel @@ -80,9 +84,12 @@ class BreakpointsProxy(breakpoints.BreakpointsService): def getIDs(self, done): done = self._makeCallback(done) service = self + class GetIDsCommand(Command): def __init__(self): - super(GetIDsCommand, self).__init__(service.channel, service, "getIDs", None) + super(GetIDsCommand, self).__init__(service.channel, service, + "getIDs", None) + def done(self, error, args): ids = None if not error: @@ -92,49 +99,63 @@ class BreakpointsProxy(breakpoints.BreakpointsService): done.doneGetIDs(self.token, error, ids) return GetIDsCommand().token - def getProperties(self, id, done): + def getProperties(self, contextID, done): done = self._makeCallback(done) service = self + class GetPropertiesCommand(Command): def __init__(self): - super(GetPropertiesCommand, self).__init__(service.channel, service, "getProperties", (id,)) + super(GetPropertiesCommand, self).__init__(service.channel, + service, + "getProperties", + (contextID,)) + def done(self, error, args): - map = None + props = None if not error: assert len(args) == 2 error = self.toError(args[0]) - map = args[1] - done.doneGetProperties(self.token, error, map) + props = args[1] + done.doneGetProperties(self.token, error, props) return GetPropertiesCommand().token - def getStatus(self, id, done): + def getStatus(self, contextID, done): done = self._makeCallback(done) service = self + class GetStatusCommand(Command): def __init__(self): - super(GetStatusCommand, self).__init__(service.channel, service, "getStatus", (id,)) + super(GetStatusCommand, self).__init__(service.channel, + service, "getStatus", + (contextID,)) + def done(self, error, args): - map = None + states = None if not error: assert len(args) == 2 error = self.toError(args[0]) - map = args[1] - done.doneGetStatus(self.token, error, map) + states = args[1] + done.doneGetStatus(self.token, error, states) return GetStatusCommand().token - def getCapabilities(self, id, done): + def getCapabilities(self, contextID, done): done = self._makeCallback(done) service = self + class GetCapabilitiesCommand(Command): def __init__(self): - super(GetCapabilitiesCommand, self).__init__(service.channel, service, "getCapabilities", (id,)) + super(GetCapabilitiesCommand, self).__init__(service.channel, + service, + "getCapabilities", + (contextID,)) + def done(self, error, args): - map = None + capabilities = None if not error: assert len(args) == 2 error = self.toError(args[0]) - map = args[1] - done.doneGetCapabilities(self.token, error, map) + capabilities = args[1] + done.doneGetCapabilities(self.token, error, capabilities) return GetCapabilitiesCommand().token def addListener(self, listener): diff --git a/python/src/tcf/services/remote/ContextQueryProxy.py b/python/src/tcf/services/remote/ContextQueryProxy.py index 2d3a420e6..002d2a414 100644 --- a/python/src/tcf/services/remote/ContextQueryProxy.py +++ b/python/src/tcf/services/remote/ContextQueryProxy.py @@ -9,8 +9,8 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf.services import contextquery -from tcf.channel.Command import Command +from .. import contextquery +from ...channel.Command import Command class ContextQueryProxy(contextquery.ContextQueryService): diff --git a/python/src/tcf/services/remote/DiagnosticsProxy.py b/python/src/tcf/services/remote/DiagnosticsProxy.py index 9c1c63b70..82e135364 100644 --- a/python/src/tcf/services/remote/DiagnosticsProxy.py +++ b/python/src/tcf/services/remote/DiagnosticsProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,12 +7,13 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import time -from tcf import errors -from tcf.services import diagnostics -from tcf.channel.Command import Command +from .. import diagnostics +from ... import errors +from ...channel.Command import Command + class DiagnosticsProxy(diagnostics.DiagnosticsService): def __init__(self, channel): @@ -21,9 +22,12 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def echo(self, s, done): done = self._makeCallback(done) service = self + class EchoCommand(Command): def __init__(self): - super(EchoCommand, self).__init__(service.channel, service, "echo", (s,)) + super(EchoCommand, self).__init__(service.channel, service, + "echo", (s,)) + def done(self, error, args): result = None if not error: @@ -35,9 +39,12 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def echoFP(self, n, done): done = self._makeCallback(done) service = self + class EchoFPCommand(Command): def __init__(self): - super(EchoFPCommand, self).__init__(service.channel, service, "echoFP", (n,)) + super(EchoFPCommand, self).__init__(service.channel, service, + "echoFP", (n,)) + def done(self, error, args): n = None if not error: @@ -47,20 +54,23 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): return EchoFPCommand().token def echoERR(self, err, done): - map = None + errMap = None if isinstance(err, errors.ErrorReport): - map = err.getAttributes() + errMap = err.getAttributes() else: - map = { + errMap = { errors.ERROR_TIME : int(time.time() * 1000), errors.ERROR_CODE : errors.TCF_ERROR_OTHER, errors.ERROR_FORMAT : err.message } done = self._makeCallback(done) service = self + class EchoERRCommand(Command): def __init__(self): - super(EchoERRCommand, self).__init__(service.channel, service, "echoERR", (map,)) + super(EchoERRCommand, self).__init__(service.channel, service, + "echoERR", (errMap,)) + def done(self, error, args): err = None result = None @@ -74,9 +84,13 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def getTestList(self, done): done = self._makeCallback(done) service = self + class GetTestListCommand(Command): def __init__(self): - super(GetTestListCommand, self).__init__(service.channel, service, "getTestList", None) + super(GetTestListCommand, self).__init__(service.channel, + service, + "getTestList", None) + def done(self, error, args): arr = None if not error: @@ -89,9 +103,12 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def runTest(self, s, done): done = self._makeCallback(done) service = self + class RunTestCommand(Command): def __init__(self): - super(RunTestCommand, self).__init__(service.channel, service, "runTest", (s,)) + super(RunTestCommand, self).__init__(service.channel, service, + "runTest", (s,)) + def done(self, error, args): result = None if not error: @@ -104,9 +121,13 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def cancelTest(self, s, done): done = self._makeCallback(done) service = self + class CancelTestCommand(Command): def __init__(self): - super(CancelTestCommand, self).__init__(service.channel, service, "cancelTest", (s,)) + super(CancelTestCommand, self).__init__(service.channel, + service, "cancelTest", + (s,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -117,9 +138,14 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def getSymbol(self, context_id, symbol_name, done): done = self._makeCallback(done) service = self + class GetSymbolCommand(Command): def __init__(self): - super(GetSymbolCommand, self).__init__(service.channel, service, "getSymbol", (context_id, symbol_name)) + super(GetSymbolCommand, self).__init__(service.channel, + service, "getSymbol", + (context_id, + symbol_name)) + def done(self, error, args): sym = None if not error: @@ -132,9 +158,14 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def createTestStreams(self, inp_buf_size, out_buf_size, done): done = self._makeCallback(done) service = self + class CreateTestStreamsCommand(Command): def __init__(self): - super(CreateTestStreamsCommand, self).__init__(service.channel, service, "createTestStreams", (inp_buf_size, out_buf_size)) + super(CreateTestStreamsCommand, + self).__init__(service.channel, service, + "createTestStreams", + (inp_buf_size, out_buf_size)) + def done(self, error, args): inp_id = None out_id = None @@ -146,12 +177,16 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): done.doneCreateTestStreams(self.token, error, inp_id, out_id) return CreateTestStreamsCommand().token - def disposeTestStream(self, id, done): + def disposeTestStream(self, streamID, done): done = self._makeCallback(done) service = self + class DisposeTestStreamCommand(Command): def __init__(self): - super(DisposeTestStreamCommand, self).__init__(service.channel, service, "disposeTestStream", (id,)) + super(DisposeTestStreamCommand, + self).__init__(service.channel, service, + "disposeTestStream", (streamID,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -162,13 +197,19 @@ class DiagnosticsProxy(diagnostics.DiagnosticsService): def not_implemented_command(self, done): done = self._makeCallback(done) service = self + class NotImplementedCommand(Command): def __init__(self): - super(NotImplementedCommand, self).__init__(service.channel, service, "not implemented command", None) + super(NotImplementedCommand, + self).__init__(service.channel, service, + "not implemented command", None) + def done(self, error, args): done.doneNotImplementedCommand(self.token, error) return NotImplementedCommand().token + def _toSymbol(o): - if o is None: return None + if o is None: + return None return diagnostics.Symbol(o) diff --git a/python/src/tcf/services/remote/DisassemblyProxy.py b/python/src/tcf/services/remote/DisassemblyProxy.py index 867c19b95..3c07edc21 100644 --- a/python/src/tcf/services/remote/DisassemblyProxy.py +++ b/python/src/tcf/services/remote/DisassemblyProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,8 +9,8 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf.services import disassembly -from tcf.channel.Command import Command +from .. import disassembly +from ...channel.Command import Command class DisassemblyProxy(disassembly.DisassemblyService): diff --git a/python/src/tcf/services/remote/ExpressionsProxy.py b/python/src/tcf/services/remote/ExpressionsProxy.py index 72529014b..19dde711b 100644 --- a/python/src/tcf/services/remote/ExpressionsProxy.py +++ b/python/src/tcf/services/remote/ExpressionsProxy.py @@ -1,4 +1,4 @@ -# ******************************************************************************* +# ***************************************************************************** # * Copyright (c) 2011, 2013 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 @@ -7,24 +7,29 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import expressions +from ... import channel +from ...channel.Command import Command -from tcf import channel -from tcf.services import expressions -from tcf.channel.Command import Command class ExpressionsProxy(expressions.ExpressionsService): def __init__(self, channel): self.channel = channel self.listeners = {} - def assign(self, id, value, done): + def assign(self, contextID, value, done): done = self._makeCallback(done) service = self value = bytearray(value) + class AssignCommand(Command): def __init__(self): - super(AssignCommand, self).__init__(service.channel, service, "assign", (id, value)) + super(AssignCommand, self).__init__(service.channel, service, + "assign", + (contextID, value)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -35,9 +40,14 @@ class ExpressionsProxy(expressions.ExpressionsService): def create(self, parent_id, language, expression, done): done = self._makeCallback(done) service = self + class CreateCommand(Command): def __init__(self): - super(CreateCommand, self).__init__(service.channel, service, "create", (parent_id, language, expression)) + super(CreateCommand, self).__init__(service.channel, service, + "create", + (parent_id, language, + expression)) + def done(self, error, args): ctx = None if not error: @@ -47,12 +57,15 @@ class ExpressionsProxy(expressions.ExpressionsService): done.doneCreate(self.token, error, ctx) return CreateCommand().token - def dispose(self, id, done): + def dispose(self, contextID, done): done = self._makeCallback(done) service = self + class DisposeCommand(Command): def __init__(self): - super(DisposeCommand, self).__init__(service.channel, service, "dispose", (id,)) + super(DisposeCommand, self).__init__(service.channel, service, + "dispose", (contextID,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -60,12 +73,15 @@ class ExpressionsProxy(expressions.ExpressionsService): done.doneDispose(self.token, error) return DisposeCommand().token - def evaluate(self, id, done): + def evaluate(self, contextID, done): done = self._makeCallback(done) service = self + class EvalCommand(Command): def __init__(self): - super(EvalCommand, self).__init__(service.channel, service, "evaluate", (id,)) + super(EvalCommand, self).__init__(service.channel, service, + "evaluate", (contextID,)) + def done(self, error, args): value = None if not error: @@ -73,15 +89,21 @@ class ExpressionsProxy(expressions.ExpressionsService): value = channel.toByteArray(args[0]) error = self.toError(args[1]) props = args[2] - done.doneEvaluate(self.token, error, expressions.Value(value, props)) + done.doneEvaluate(self.token, error, + expressions.Value(value, props)) return EvalCommand().token def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -91,18 +113,23 @@ class ExpressionsProxy(expressions.ExpressionsService): done.doneGetChildren(self.token, error, contexts) return GetChildrenCommand().token - def getContext(self, id, done): + def getContext(self, contextID, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (contextID,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = expressions.Expression(args[1]) + if args[1]: + ctx = expressions.Expression(args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token @@ -122,6 +149,7 @@ class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -129,6 +157,6 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 1 self.listener.valueChanged(args[0]) else: - raise IOError("Expressions service: unknown event: " + name); + raise IOError("Expressions service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) diff --git a/python/src/tcf/services/remote/FileSystemProxy.py b/python/src/tcf/services/remote/FileSystemProxy.py index 11fdb6a08..69b4d8eb6 100644 --- a/python/src/tcf/services/remote/FileSystemProxy.py +++ b/python/src/tcf/services/remote/FileSystemProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,9 +9,9 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf import errors, channel -from tcf.services import filesystem -from tcf.channel.Command import Command +from .. import filesystem +from ... import errors, channel +from ...channel.Command import Command class Status(filesystem.FileSystemException): diff --git a/python/src/tcf/services/remote/LineNumbersProxy.py b/python/src/tcf/services/remote/LineNumbersProxy.py index 7452cc761..5436bd695 100644 --- a/python/src/tcf/services/remote/LineNumbersProxy.py +++ b/python/src/tcf/services/remote/LineNumbersProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,23 +7,28 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import linenumbers +from ...channel.Command import Command -from tcf.services import linenumbers -from tcf.channel.Command import Command class LineNumbersProxy(linenumbers.LineNumbersService): def __init__(self, channel): self.channel = channel - def mapToSource(self, context_id, start_address, end_address, done): + def mapToSource(self, context_id, start_address, end_address, done): done = self._makeCallback(done) service = self + class MapCommand(Command): def __init__(self): super(MapCommand, self).__init__(service.channel, service, - "mapToSource", (context_id, start_address, end_address)) + "mapToSource", + (context_id, start_address, + end_address)) + def done(self, error, args): arr = None if not error: @@ -33,13 +38,17 @@ class LineNumbersProxy(linenumbers.LineNumbersService): done.doneMapToSource(self.token, error, arr) return MapCommand().token - def mapToMemory(self, context_id, file, line, column, done): + def mapToMemory(self, context_id, filePath, line, column, done): done = self._makeCallback(done) service = self + class MapCommand(Command): def __init__(self): super(MapCommand, self).__init__(service.channel, service, - "mapToMemory", (context_id, file, line, column)) + "mapToMemory", + (context_id, filePath, line, + column)) + def done(self, error, args): arr = None if not error: @@ -49,15 +58,17 @@ class LineNumbersProxy(linenumbers.LineNumbersService): done.doneMapToMemory(self.token, error, arr) return MapCommand().token + def _toCodeAreaArray(o): - if not o: return None + if not o: + return None arr = [] directory = None - file = None + filePath = None for area in o: directory = area.get("Dir", directory) - file = area.get("File", file) - arr.append(linenumbers.CodeArea(directory, file, + filePath = area.get("File", filePath) + arr.append(linenumbers.CodeArea(directory, filePath, area.get("SLine", 0), area.get("SCol", 0), area.get("ELine", 0), area.get("ECol", 0), area.get("SAddr"), area.get("EAddr"), diff --git a/python/src/tcf/services/remote/LocatorProxy.py b/python/src/tcf/services/remote/LocatorProxy.py index d9963686e..730c095bb 100644 --- a/python/src/tcf/services/remote/LocatorProxy.py +++ b/python/src/tcf/services/remote/LocatorProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,26 +7,30 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import locator +from ... import protocol, peer, channel +from ...channel.Command import Command -from tcf import protocol, peer, channel -from tcf.services import locator -from tcf.channel.Command import Command class Peer(peer.TransientPeer): def __init__(self, parent, attrs): super(Peer, self).__init__(attrs) self.parent = parent + def openChannel(self): assert protocol.isDispatchThread() c = self.parent.openChannel() c.redirect(self.getID()) return c + class ChannelEventListener(channel.EventListener): def __init__(self, proxy): self.proxy = proxy self.channel = proxy.channel + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -41,48 +45,58 @@ class ChannelEventListener(channel.EventListener): try: l.peerAdded(_peer) except Exception as x: - protocol.log("Unhandled exception in Locator listener", x) + protocol.log("Unhandled exception in Locator listener", + x) elif name == "peerChanged": assert len(args) == 1 m = args[0] - if not m: raise Exception("Locator service: invalid peerChanged event - no peer ID") + if not m: + raise Exception("Locator service: invalid peerChanged " + + "event - no peer ID") _peer = self.proxy.peers.get(m.get(peer.ATTR_ID)) - if not _peer: return + if not _peer: + return self.proxy.peers[_peer.getID()] = _peer for l in self.proxy.listeners: try: l.peerChanged(_peer) except Exception as x: - protocol.log("Unhandled exception in Locator listener", x) + protocol.log("Unhandled exception in Locator listener", + x) elif name == "peerRemoved": assert len(args) == 1 - id = args[0] - _peer = self.proxy.peers.get(id) - if not _peer: return - del self.proxy.peers[id] + peerID = args[0] + _peer = self.proxy.peers.get(peerID) + if not _peer: + return + del self.proxy.peers[peerID] for l in self.proxy.listeners: try: - l.peerRemoved(id) + l.peerRemoved(peerID) except Exception as x: - protocol.log("Unhandled exception in Locator listener", x) + protocol.log("Unhandled exception in Locator listener", + x) elif name == "peerHeartBeat": assert len(args) == 1 - id = args[0] - _peer = self.proxy.peers.get(id) - if not _peer: return + peerID = args[0] + _peer = self.proxy.peers.get(peerID) + if not _peer: + return for l in self.proxy.listeners: try: - l.peerHeartBeat(id) + l.peerHeartBeat(peerID) except Exception as x: - protocol.log("Unhandled exception in Locator listener", x) + protocol.log("Unhandled exception in Locator listener", + x) else: raise IOError("Locator service: unknown event: " + name) except Exception as x: self.channel.terminate(x) + class LocatorProxy(locator.LocatorService): def __init__(self, channel): - self.channel = channel; + self.channel = channel self.peers = {} self.listeners = [] self.get_peers_done = False @@ -95,9 +109,12 @@ class LocatorProxy(locator.LocatorService): def redirect(self, _peer, done): done = self._makeCallback(done) service = self + class RedirectCommand(Command): def __init__(self): - super(RedirectCommand, self).__init__(service.channel, service, "redirect", [_peer]) + super(RedirectCommand, self).__init__(service.channel, service, + "redirect", [_peer]) + def done(self, error, args): if not error: assert len(args) == 1 @@ -108,11 +125,15 @@ class LocatorProxy(locator.LocatorService): def sync(self, done): done = self._makeCallback(done) service = self + class SyncCommand(Command): def __init__(self): - super(SyncCommand, self).__init__(service.channel, service, "sync", None) + super(SyncCommand, self).__init__(service.channel, service, + "sync", None) + def done(self, error, args): - if error: service.channel.terminate(error) + if error: + service.channel.terminate(error) done.doneSync(self.token) return SyncCommand().token @@ -120,9 +141,13 @@ class LocatorProxy(locator.LocatorService): self.listeners.append(listener) if not self.get_peers_done: service = self + class GetPeersCommand(Command): def __init__(self): - super(GetPeersCommand, self).__init__(service.channel, service, "getPeers", None) + super(GetPeersCommand, self).__init__(service.channel, + service, "getPeers", + None) + def done(self, error, args): if not error: assert len(args) == 2 @@ -133,15 +158,17 @@ class LocatorProxy(locator.LocatorService): c = args[1] if c: for m in c: - id = m.get(peer.ATTR_ID) - if service.peers.get(id): continue; + peerID = m.get(peer.ATTR_ID) + if service.peers.get(peerID): + continue _peer = Peer(service.channel.getRemotePeer(), m) - service.peers[id] = _peer + service.peers[peerID] = _peer for l in service.listeners: try: l.peerAdded(_peer) except Exception as x: - protocol.log("Unhandled exception in Locator listener", x) + protocol.log("Unhandled exception in " + + "Locator listener", x) GetPeersCommand() self.get_peers_done = True diff --git a/python/src/tcf/services/remote/MemoryMapProxy.py b/python/src/tcf/services/remote/MemoryMapProxy.py index 34aab1d5f..f21eaf0a4 100644 --- a/python/src/tcf/services/remote/MemoryMapProxy.py +++ b/python/src/tcf/services/remote/MemoryMapProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,40 +7,49 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import memorymap +from ... import channel +from ...channel.Command import Command -from tcf import channel -from tcf.services import memorymap -from tcf.channel.Command import Command class MemoryMapProxy(memorymap.MemoryMapService): def __init__(self, channel): self.channel = channel self.listeners = {} - def get(self, id, done): + def get(self, contextID, done): done = self._makeCallback(done) service = self + class GetCommand(Command): def __init__(self): - super(GetCommand, self).__init__(service.channel, service, "get", (id,)) + super(GetCommand, self).__init__(service.channel, service, + "get", (contextID,)) + def done(self, error, args): - map = None + memMap = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: map = _toMemoryMap(args[1]) - done.doneGet(self.token, error, map) + if args[1]: + memMap = _toMemoryMap(args[1]) + done.doneGet(self.token, error, memMap) return GetCommand().token - def set(self, id, map, done): - if isinstance(map, memorymap.MemoryRegion) or isinstance(map, dict): - map = (map,) + def set(self, contextID, memMap, done): + if isinstance(memMap, memorymap.MemoryRegion) or \ + isinstance(memMap, dict): + memMap = (memMap,) done = self._makeCallback(done) service = self + class SetCommand(Command): def __init__(self): - super(SetCommand, self).__init__(service.channel, service, "set", (id, map)) + super(SetCommand, self).__init__(service.channel, service, + "set", (contextID, memMap)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -55,12 +64,15 @@ class MemoryMapProxy(memorymap.MemoryMapService): def removeListener(self, listener): l = self.listeners.pop(listener, None) - if l: self.channel.removeEventListener(self, l) + if l: + self.channel.removeEventListener(self, l) + class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -68,15 +80,18 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 1 self.listener.changed(args[0]) else: - raise IOError("MemoryMap service: unknown event: " + name); + raise IOError("MemoryMap service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) def _toMemoryMap(o): - if o is None: return None + if o is None: + return None return map(_toMemoryRegion, o) + def _toMemoryRegion(o): - if o is None: return None + if o is None: + return None return memorymap.MemoryRegion(o) diff --git a/python/src/tcf/services/remote/MemoryProxy.py b/python/src/tcf/services/remote/MemoryProxy.py index 8cf9f302e..8d84d3746 100644 --- a/python/src/tcf/services/remote/MemoryProxy.py +++ b/python/src/tcf/services/remote/MemoryProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,21 +9,27 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf import errors, channel -from tcf.services import memory -from tcf.channel.Command import Command +from .. import memory +from ... import errors, channel +from ...channel.Command import Command + class Range(object): offs = 0 size = 0 stat = 0 msg = None + def __cmp__(self, o): - if self.offs < o.offs: return -1 - if self.offs > o.offs: return +1 + if self.offs < o.offs: + return -1 + if self.offs > o.offs: + return +1 return 0 -class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, memory.ErrorOffset): + +class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, + memory.ErrorOffset): def __init__(self, msg, attrs, addr, ranges): super(MemoryErrorReport, self).__init__(msg, attrs) if ranges is None: @@ -40,14 +46,16 @@ class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, memory.ErrorOffs r.offs = y - addr r.size = m.get(memory.ErrorOffset.RANGE_KEY_SIZE) r.stat = m.get(memory.ErrorOffset.RANGE_KEY_STAT) - r.msg = errors.toErrorString(m.get(memory.ErrorOffset.RANGE_KEY_MSG)) + key = memory.ErrorOffset.RANGE_KEY_MSG + r.msg = errors.toErrorString(m.get(key)) assert r.offs >= 0 assert r.size >= 0 self.ranges.append(r) self.ranges.sort() def getMessage(self, offset): - if self.ranges is None: return None + if self.ranges is None: + return None l = 0 h = len(self.ranges) - 1 while l <= h: @@ -62,7 +70,8 @@ class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, memory.ErrorOffs return None def getStatus(self, offset): - if self.ranges is None: return memory.ErrorOffset.BYTE_UNKNOWN + if self.ranges is None: + return memory.ErrorOffset.BYTE_UNKNOWN l = 0 h = len(self.ranges) - 1 while l <= h: @@ -84,12 +93,15 @@ class MemContext(memory.MemoryContext): def fill(self, addr, word_size, value, size, mode, done): service = self.service - id = self.getID() + contextID = self.getID() done = service._makeCallback(done) + class FillCommand(MemoryCommand): def __init__(self): - super(FillCommand, self).__init__(service, - "fill", (id, addr, word_size, size, mode, value)) + super(FillCommand, self).__init__(service, "fill", + (contextID, addr, word_size, + size, mode, value)) + def done(self, error, args): e = None if error: @@ -102,12 +114,15 @@ class MemContext(memory.MemoryContext): def get(self, addr, word_size, buf, offs, size, mode, done): service = self.service - id = self.getID() + contextID = self.getID() done = service._makeCallback(done) + class GetCommand(MemoryCommand): def __init__(self): - super(GetCommand, self).__init__(service, - "get", (id, addr, word_size, size, mode)) + super(GetCommand, self).__init__(service, "get", + (contextID, addr, word_size, + size, mode)) + def done(self, error, args): e = None if error: @@ -116,19 +131,24 @@ class MemContext(memory.MemoryContext): assert len(args) == 3 byts = channel.toByteArray(args[0]) assert len(byts) <= size - buf[offs:offs+len(byts)] = byts + buf[offs:offs + len(byts)] = byts e = self.toMemoryError(addr, args[1], args[2]) done.doneMemory(self.token, e) return GetCommand().token def set(self, addr, word_size, buf, offs, size, mode, done): service = self.service - id = self.getID() + contextID = self.getID() done = service._makeCallback(done) + class SetCommand(MemoryCommand): def __init__(self): - super(SetCommand, self).__init__(service, - "set", (id, addr, word_size, size, mode, bytearray(buf[offs:offs+size]))) + super(SetCommand, self).__init__(service, "set", + (contextID, addr, word_size, + size, mode, + bytearray(buf[offs:offs + + size]))) + def done(self, error, args): e = None if error: @@ -139,6 +159,7 @@ class MemContext(memory.MemoryContext): done.doneMemory(self.token, e) return SetCommand().token + class MemoryProxy(memory.MemoryService): def __init__(self, channel): self.channel = channel @@ -147,24 +168,34 @@ class MemoryProxy(memory.MemoryService): def getContext(self, context_id, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (context_id,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = MemContext(service, args[1]) + if args[1]: + ctx = MemContext(service, args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -185,20 +216,26 @@ class MemoryProxy(memory.MemoryService): del self.listeners[listener] self.channel.removeEventListener(self, l) + class MemoryCommand(Command): def __init__(self, service, cmd, args): - super(MemoryCommand, self).__init__(service.channel, service, cmd, args) + super(MemoryCommand, self).__init__(service.channel, service, cmd, + args) + def toMemoryError(self, addr, data, ranges): - if data is None: return None + if data is None: + return None code = data.get(errors.ERROR_CODE) cmd = self.getCommandString() - if len(cmd) > 72: cmd = cmd[0:72] + "..." - e = MemoryErrorReport( - "TCF command exception:\nCommand: %s\nException: %s\nError code: %d" % ( - cmd, errors.toErrorString(data), code), + if len(cmd) > 72: + cmd = cmd[0:72] + "..." + e = MemoryErrorReport("TCF command exception:\nCommand: %s\n" + + "Exception: %s\nError code: %d" % + (cmd, errors.toErrorString(data), code), data, addr, ranges) caused_by = data.get(errors.ERROR_CAUSED_BY) - if caused_by is not None: e.caused_by = self.toError(caused_by, False) + if caused_by is not None: + e.caused_by = self.toError(caused_by, False) return e @@ -206,37 +243,47 @@ class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) if name == "contextAdded": assert len(args) == 1 - self.listener.contextAdded(_toContextArray(self.service, args[0])) + self.listener.contextAdded(_toContextArray(self.service, + args[0])) elif name == "contextChanged": assert len(args) == 1 - self.listener.contextChanged(_toContextArray(self.service, args[0])) + self.listener.contextChanged(_toContextArray(self.service, + args[0])) elif name == "contextRemoved": assert len(args) == 1 self.listener.contextRemoved(args[0]) elif name == "memoryChanged": assert len(args) == 2 - self.listener.memoryChanged(args[0], _toAddrArray(args[1]), _toSizeArray(args[1])) + self.listener.memoryChanged(args[0], _toAddrArray(args[1]), + _toSizeArray(args[1])) else: - raise IOError("Memory service: unknown event: " + name); + raise IOError("Memory service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) def _toContextArray(svc, o): - if o is None: return None + if o is None: + return None ctx = [] - for m in o: ctx.append(MemContext(svc, m)) + for m in o: + ctx.append(MemContext(svc, m)) return ctx + def _toSizeArray(o): - if o is None: return None + if o is None: + return None return map(lambda m: m.get("size", 0), o) + def _toAddrArray(o): - if o is None: return None + if o is None: + return None return map(lambda m: m.get("addr"), o) diff --git a/python/src/tcf/services/remote/PathMapProxy.py b/python/src/tcf/services/remote/PathMapProxy.py index 28f64881f..b4755521b 100644 --- a/python/src/tcf/services/remote/PathMapProxy.py +++ b/python/src/tcf/services/remote/PathMapProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,9 +9,9 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf import channel -from tcf.services import pathmap -from tcf.channel.Command import Command +from .. import pathmap +from ... import channel +from ...channel.Command import Command class ChannelEventListener(channel.EventListener): diff --git a/python/src/tcf/services/remote/ProcessesProxy.py b/python/src/tcf/services/remote/ProcessesProxy.py index eeba4dcd6..bb9b5f9a6 100644 --- a/python/src/tcf/services/remote/ProcessesProxy.py +++ b/python/src/tcf/services/remote/ProcessesProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,11 +7,12 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import processes +from ... import channel +from ...channel.Command import Command -from tcf import channel -from tcf.services import processes -from tcf.channel.Command import Command class ProcessContext(processes.ProcessContext): def __init__(self, service, props): @@ -30,11 +31,13 @@ class ProcessContext(processes.ProcessContext): def _command(self, command, done): service = self.service done = service._makeCallback(done) - id = self.getID() + contextID = self.getID() + class _Command(Command): def __init__(self): super(_Command, self).__init__(service.channel, service, - command, (id,)) + command, (contextID,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -42,6 +45,7 @@ class ProcessContext(processes.ProcessContext): done.doneCommand(self.token, error) return _Command().token + class ProcessesProxy(processes.ProcessesService): def __init__(self, channel): self.channel = channel @@ -50,10 +54,15 @@ class ProcessesProxy(processes.ProcessesService): def getChildren(self, parent_context_id, attached_only, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, - "getChildren", (parent_context_id, attached_only)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id, + attached_only)) + def done(self, error, args): contexts = None if not error: @@ -66,24 +75,32 @@ class ProcessesProxy(processes.ProcessesService): def getContext(self, context_id, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (context_id,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = ProcessContext(service, args[1]) + if args[1]: + ctx = ProcessContext(service, args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token def getEnvironment(self, done): done = self._makeCallback(done) service = self + class GetEnvCommand(Command): def __init__(self): - super(GetEnvCommand, self).__init__(service.channel, service, "getEnvironment", None) + super(GetEnvCommand, self).__init__(service.channel, service, + "getEnvironment", None) + def done(self, error, args): env = None if not error: @@ -93,46 +110,60 @@ class ProcessesProxy(processes.ProcessesService): done.doneGetEnvironment(self.token, error, env) return GetEnvCommand().token - def start(self, directory, file, command_line, environment, attach, done): + def start(self, directory, filePath, command_line, environment, attach, + done): done = self._makeCallback(done) service = self env = _toEnvStringArray(environment) + class StartCommand(Command): def __init__(self): super(StartCommand, self).__init__(service.channel, service, - "start", (directory, file, command_line, env, attach)) + "start", + (directory, filePath, + command_line, env, attach)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = ProcessContext(service, args[1]) + if args[1]: + ctx = ProcessContext(service, args[1]) done.doneStart(self.token, error, ctx) return StartCommand().token def getSignalList(self, context_id, done): done = self._makeCallback(done) service = self + class GetSignalsCommand(Command): def __init__(self): - super(GetSignalsCommand, self).__init__(service.channel, service, - "getSignalList", (context_id,)) + super(GetSignalsCommand, self).__init__(service.channel, + service, + "getSignalList", + (context_id,)) + def done(self, error, args): - list = None + lst = None if not error: assert len(args) == 2 error = self.toError(args[0]) - list = args[1] - done.doneGetSignalList(self.token, error, list) + lst = args[1] + done.doneGetSignalList(self.token, error, lst) return GetSignalsCommand().token def getSignalMask(self, context_id, done): done = self._makeCallback(done) service = self + class GetSignalMaskCommand(Command): def __init__(self): - super(GetSignalMaskCommand, self).__init__(service.channel, service, - "getSignalMask", (context_id,)) + super(GetSignalMaskCommand, self).__init__(service.channel, + service, + "getSignalMask", + (context_id,)) + def done(self, error, args): dont_stop = 0 dont_pass = 0 @@ -141,16 +172,23 @@ class ProcessesProxy(processes.ProcessesService): assert len(args) == 4 error = self.toError(args[0]) dont_stop, dont_pass, pending = args[1:4] - done.doneGetSignalMask(self.token, error, dont_stop, dont_pass, pending) + done.doneGetSignalMask(self.token, error, dont_stop, dont_pass, + pending) return GetSignalMaskCommand().token def setSignalMask(self, context_id, dont_stop, dont_pass, done): done = self._makeCallback(done) service = self + class SetSignalMaskCommand(Command): def __init__(self): - super(SetSignalMaskCommand, self).__init__(service.channel, service, - "setSignalMask", (context_id, dont_stop, dont_pass)) + super(SetSignalMaskCommand, self).__init__(service.channel, + service, + "setSignalMask", + (context_id, + dont_stop, + dont_pass)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -161,10 +199,13 @@ class ProcessesProxy(processes.ProcessesService): def signal(self, context_id, signal, done): done = self._makeCallback(done) service = self + class SignalCommand(Command): def __init__(self): - super(SignalCommand, self).__init__(service.channel, service, - "signal", (context_id, signal)) + super(SignalCommand, self).__init__(service.channel, + service, "signal", + (context_id, signal)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -183,10 +224,12 @@ class ProcessesProxy(processes.ProcessesService): del self.listeners[listener] self.channel.removeEventListener(self, l) + class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -194,22 +237,28 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 2 self.listener.exited(args[0], args[1]) else: - raise IOError("Processes service: unknown event: " + name); + raise IOError("Processes service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) -def _toEnvStringArray(map): + +def _toEnvStringArray(envVars): arr = [] - if not map: return arr - for name, value in map.items(): + if not envVars: + return arr + for name, value in envVars.items(): arr.append("%s=%s" % (name, value)) return arr + def _toEnvMap(arr): - map = {} - if not arr: return map + envVars = {} + if not arr: + return envVars for env in arr: i = env.find('=') - if i >= 0: map[env[:i]] = env[i + 1:] - else: map[env] = "" - return map + if i >= 0: + envVars[env[:i]] = env[i + 1:] + else: + envVars[env] = "" + return envVars diff --git a/python/src/tcf/services/remote/ProcessesV1Proxy.py b/python/src/tcf/services/remote/ProcessesV1Proxy.py index c16d15624..883b9d457 100644 --- a/python/src/tcf/services/remote/ProcessesV1Proxy.py +++ b/python/src/tcf/services/remote/ProcessesV1Proxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,26 +7,35 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** from . import ProcessesProxy -from tcf.services import processes_v1 -from tcf.channel.Command import Command +from .. import processes_v1 +from ...channel.Command import Command -class ProcessesV1Proxy(ProcessesProxy.ProcessesProxy, processes_v1.ProcessesV1Service): - def start(self, directory, file, command_line, environment, params, done): + +class ProcessesV1Proxy(ProcessesProxy.ProcessesProxy, + processes_v1.ProcessesV1Service): + + def start(self, directory, filePath, command_line, environment, params, + done): done = self._makeCallback(done) service = self env = ProcessesProxy._toEnvStringArray(environment) + class StartCommand(Command): def __init__(self): super(StartCommand, self).__init__(service.channel, service, - "start", (directory, file, command_line, env, params)) + "start", + (directory, filePath, + command_line, env, params)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = ProcessesProxy.ProcessContext(service, args[1]) + if args[1]: + ctx = ProcessesProxy.ProcessContext(service, args[1]) done.doneStart(self.token, error, ctx) return StartCommand().token diff --git a/python/src/tcf/services/remote/RegistersProxy.py b/python/src/tcf/services/remote/RegistersProxy.py index fdf3d9ae8..aa52f34b4 100644 --- a/python/src/tcf/services/remote/RegistersProxy.py +++ b/python/src/tcf/services/remote/RegistersProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,12 +7,13 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import registers +from ... import channel +from ...channel import toByteArray +from ...channel.Command import Command -from tcf import channel -from tcf.services import registers -from tcf.channel import toByteArray -from tcf.channel.Command import Command class Context(registers.RegistersContext): def __init__(self, service, props): @@ -25,10 +26,13 @@ class Context(registers.RegistersContext): def get(self, done): service = self.service done = service._makeCallback(done) - id = self.getID() + contextID = self.getID() + class GetCommand(Command): def __init__(self): - super(GetCommand, self).__init__(service.channel, service, "get", (id,)) + super(GetCommand, self).__init__(service.channel, service, + "get", (contextID,)) + def done(self, error, args): val = None if not error: @@ -41,11 +45,14 @@ class Context(registers.RegistersContext): def set(self, value, done): service = self.service done = service._makeCallback(done) - id = self.getID() + contextID = self.getID() binary = bytearray(value) + class SetCommand(Command): def __init__(self): - super(SetCommand, self).__init__(service.channel, service, "set", (id, binary)) + super(SetCommand, self).__init__(service.channel, service, + "set", (contextID, binary)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -53,13 +60,17 @@ class Context(registers.RegistersContext): done.doneSet(self.token, error) return SetCommand().token - def search(self, filter, done): + def search(self, filterOn, done): service = self.service done = service._makeCallback(done) - id = self.getID() + contextID = self.getID() + class SearchCommand(Command): def __init__(self): - super(SearchCommand, self).__init__(service.channel, service, "search", (id, filter)) + super(SearchCommand, self).__init__(service.channel, service, + "search", + (contextID, filterOn)) + def done(self, error, args): paths = None if not error: @@ -69,6 +80,7 @@ class Context(registers.RegistersContext): done.doneSearch(self.token, error, paths) return SearchCommand().token + class RegistersProxy(registers.RegistersService): def __init__(self, channel): self.channel = channel @@ -77,9 +89,14 @@ class RegistersProxy(registers.RegistersService): def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -89,27 +106,35 @@ class RegistersProxy(registers.RegistersService): done.doneGetChildren(self.token, error, contexts) return GetChildrenCommand().token - def getContext(self, id, done): + def getContext(self, contextID, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (contextID,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = Context(service, args[1]) + if args[1]: + ctx = Context(service, args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token def getm(self, locs, done): done = self._makeCallback(done) service = self + class GetMCommand(Command): def __init__(self): - super(GetMCommand, self).__init__(service.channel, service, "getm", (locs,)) + super(GetMCommand, self).__init__(service.channel, service, + "getm", (locs,)) + def done(self, error, args): val = None if not error: @@ -123,9 +148,12 @@ class RegistersProxy(registers.RegistersService): done = self._makeCallback(done) service = self binary = bytearray(value) + class SetMCommand(Command): def __init__(self): - super(SetMCommand, self).__init__(service.channel, service, "setm", (locs, binary)) + super(SetMCommand, self).__init__(service.channel, service, + "setm", (locs, binary)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -144,6 +172,7 @@ class RegistersProxy(registers.RegistersService): del self.listeners[listener] self.channel.removeEventListener(self, l) + class NamedValueInfo(registers.NamedValue): def __init__(self, m): desc = m.get("Description") @@ -151,17 +180,21 @@ class NamedValueInfo(registers.NamedValue): value = toByteArray(m.get("Value")) super(NamedValueInfo, self).__init__(value, name, desc) + def _toValuesArray(o): - if o is None: return None + if o is None: + return None arr = [] for m in o: arr.append(NamedValueInfo(m)) return arr + class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -171,6 +204,6 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 1 self.listener.registerChanged(args[0]) else: - raise IOError("Registers service: unknown event: " + name); + raise IOError("Registers service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) diff --git a/python/src/tcf/services/remote/RunControlProxy.py b/python/src/tcf/services/remote/RunControlProxy.py index 60d20fea8..8aef1bcaa 100644 --- a/python/src/tcf/services/remote/RunControlProxy.py +++ b/python/src/tcf/services/remote/RunControlProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,11 +7,12 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import runcontrol +from ... import channel +from ...channel.Command import Command -from tcf import channel -from tcf.services import runcontrol -from tcf.channel.Command import Command class RunContext(runcontrol.RunControlContext): def __init__(self, service, props): @@ -21,23 +22,27 @@ class RunContext(runcontrol.RunControlContext): def getState(self, done): service = self.service done = service._makeCallback(done) - id = self.getID() + contextID = self.getID() + class GetStateCommand(Command): def __init__(self): - super(GetStateCommand, self).__init__(service.channel, service, "getState", (id,)) + super(GetStateCommand, self).__init__(service.channel, service, + "getState", (contextID,)) + def done(self, error, args): susp = False pc = None reason = None - map = None + states = None if not error: assert len(args) == 5 error = self.toError(args[0]) susp = args[1] - if args[2]: pc = str(args[2]) + if args[2]: + pc = str(args[2]) reason = args[3] - map = args[4] - done.doneGetState(self.token, error, susp, pc, reason, map) + states = args[4] + done.doneGetState(self.token, error, susp, pc, reason, states) return GetStateCommand().token # def resume(self, mode, count, done): @@ -47,7 +52,8 @@ class RunContext(runcontrol.RunControlContext): if not params: return self._command("resume", (self.getID(), mode, count), done) else: - return self._command("resume", (self.getID(), mode, count, params), done) + return self._command("resume", (self.getID(), mode, count, params), + done) def suspend(self, done): return self._command("suspend", (self.getID(),), done) @@ -58,9 +64,12 @@ class RunContext(runcontrol.RunControlContext): def _command(self, cmd, args, done): service = self.service done = service._makeCallback(done) + class RCCommand(Command): def __init__(self, cmd, args): - super(RCCommand, self).__init__(service.channel, service, cmd, args) + super(RCCommand, self).__init__(service.channel, service, cmd, + args) + def done(self, error, args): if not error: assert len(args) == 1 @@ -73,21 +82,25 @@ class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) if name == "contextSuspended": assert len(args) == 4 - self.listener.contextSuspended(args[0], args[1], args[2], args[3]) + self.listener.contextSuspended(args[0], args[1], args[2], + args[3]) elif name == "contextResumed": assert len(args) == 1 self.listener.contextResumed(args[0]) elif name == "contextAdded": assert len(args) == 1 - self.listener.contextAdded(_toContextArray(self.service,args[0])) + self.listener.contextAdded(_toContextArray(self.service, + args[0])) elif name == "contextChanged": assert len(args) == 1 - self.listener.contextChanged(_toContextArray(self.service,args[0])) + self.listener.contextChanged(_toContextArray(self.service, + args[0])) elif name == "contextRemoved": assert len(args) == 1 self.listener.contextRemoved(args[0]) @@ -96,15 +109,17 @@ class ChannelEventListener(channel.EventListener): self.listener.contextException(args[0], args[1]) elif name == "containerSuspended": assert len(args) == 5 - self.listener.containerSuspended(args[0], args[1], args[2], args[3], args[4]) + self.listener.containerSuspended(args[0], args[1], args[2], + args[3], args[4]) elif name == "containerResumed": assert len(args) == 1 self.listener.containerResumed(args[0]) else: - raise IOError("RunControl service: unknown event: " + name); + raise IOError("RunControl service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) + class RunControlProxy(runcontrol.RunControlService): def __init__(self, channel): self.channel = channel @@ -124,24 +139,34 @@ class RunControlProxy(runcontrol.RunControlService): def getContext(self, context_id, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (context_id,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = RunContext(service, args[1]) + if args[1]: + ctx = RunContext(service, args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -151,8 +176,11 @@ class RunControlProxy(runcontrol.RunControlService): done.doneGetChildren(self.token, error, contexts) return GetChildrenCommand().token -def _toContextArray(svc,o): - if o is None: return None + +def _toContextArray(svc, o): + if o is None: + return None ctx = [] - for m in o: ctx.append(RunContext(svc,m)) + for m in o: + ctx.append(RunContext(svc, m)) return ctx diff --git a/python/src/tcf/services/remote/StackTraceProxy.py b/python/src/tcf/services/remote/StackTraceProxy.py index 5a2d6288f..843cf1e8c 100644 --- a/python/src/tcf/services/remote/StackTraceProxy.py +++ b/python/src/tcf/services/remote/StackTraceProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,10 +7,11 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import stacktrace +from ...channel.Command import Command -from tcf.services import stacktrace -from tcf.channel.Command import Command class StackTraceProxy(stacktrace.StackTraceService): def __init__(self, channel): @@ -19,9 +20,14 @@ class StackTraceProxy(stacktrace.StackTraceService): def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -34,9 +40,13 @@ class StackTraceProxy(stacktrace.StackTraceService): def getContext(self, ids, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (ids,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (ids,)) + def done(self, error, args): ctxs = None if not error: @@ -47,7 +57,8 @@ class StackTraceProxy(stacktrace.StackTraceService): return GetContextCommand().token def toContextArray(self, ctxProps): - if ctxProps is None: return None + if ctxProps is None: + return None ctxs = [] for props in ctxProps: ctxs.append(stacktrace.StackTraceContext(props)) diff --git a/python/src/tcf/services/remote/StreamsProxy.py b/python/src/tcf/services/remote/StreamsProxy.py index 67297e7d1..d249a5b93 100644 --- a/python/src/tcf/services/remote/StreamsProxy.py +++ b/python/src/tcf/services/remote/StreamsProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,11 +7,12 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import streams +from ... import channel +from ...channel.Command import Command -from tcf.services import streams -from tcf import channel -from tcf.channel.Command import Command class StreamsProxy(streams.StreamsService): def __init__(self, channel): @@ -21,9 +22,12 @@ class StreamsProxy(streams.StreamsService): def connect(self, stream_id, done): done = self._makeCallback(done) service = self + class ConnectCommand(Command): def __init__(self): - super(ConnectCommand, self).__init__(service.channel, service, "connect", (stream_id,)) + super(ConnectCommand, self).__init__(service.channel, service, + "connect", (stream_id,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -34,9 +38,13 @@ class StreamsProxy(streams.StreamsService): def disconnect(self, stream_id, done): done = self._makeCallback(done) service = self + class DisconnectCommand(Command): def __init__(self): - super(DisconnectCommand, self).__init__(service.channel, service, "disconnect", (stream_id,)) + super(DisconnectCommand, self).__init__(service.channel, + service, "disconnect", + (stream_id,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -47,9 +55,12 @@ class StreamsProxy(streams.StreamsService): def eos(self, stream_id, done): done = self._makeCallback(done) service = self + class EOSCommand(Command): def __init__(self): - super(EOSCommand, self).__init__(service.channel, service, "eos", (stream_id,)) + super(EOSCommand, self).__init__(service.channel, service, + "eos", (stream_id,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -60,9 +71,12 @@ class StreamsProxy(streams.StreamsService): def read(self, stream_id, size, done): done = self._makeCallback(done) service = self + class ReadCommand(Command): def __init__(self): - super(ReadCommand, self).__init__(service.channel, service, "read", (stream_id, size)) + super(ReadCommand, self).__init__(service.channel, service, + "read", (stream_id, size)) + def done(self, error, args): lost_size = 0 data = None @@ -79,9 +93,13 @@ class StreamsProxy(streams.StreamsService): def subscribe(self, stream_type, listener, done): done = self._makeCallback(done) service = self + class SubscribeCommand(Command): def __init__(self): - super(SubscribeCommand, self).__init__(service.channel, service, "subscribe", (stream_type,)) + super(SubscribeCommand, self).__init__(service.channel, + service, "subscribe", + (stream_type,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -96,26 +114,36 @@ class StreamsProxy(streams.StreamsService): def unsubscribe(self, stream_type, listener, done): done = self._makeCallback(done) service = self + class UnsubscribeCommand(Command): def __init__(self): - super(UnsubscribeCommand, self).__init__(service.channel, service, "unsubscribe", (stream_type,)) + super(UnsubscribeCommand, self).__init__(service.channel, + service, + "unsubscribe", + (stream_type,)) + def done(self, error, args): if not error: assert len(args) == 1 error = self.toError(args[0]) if not error: l = service.listeners.pop(listener, None) - if l: service.channel.removeEventListener(service, l) + if l: + service.channel.removeEventListener(service, l) done.doneUnsubscribe(self.token, error) return UnsubscribeCommand().token def write(self, stream_id, buf, offset, size, done): done = self._makeCallback(done) service = self - binary = buf[offset:offset+size] + binary = buf[offset:offset + size] + class WriteCommand(Command): def __init__(self): - super(WriteCommand, self).__init__(service.channel, service, "write", (stream_id, binary)) + super(WriteCommand, self).__init__(service.channel, service, + "write", + (stream_id, binary)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -128,6 +156,7 @@ class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -141,6 +170,6 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 2 self.listener.disposed(args[0], args[1]) else: - raise IOError("Streams service: unknown event: " + name); + raise IOError("Streams service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) diff --git a/python/src/tcf/services/remote/SymbolsProxy.py b/python/src/tcf/services/remote/SymbolsProxy.py index a8556f1df..29966ecce 100644 --- a/python/src/tcf/services/remote/SymbolsProxy.py +++ b/python/src/tcf/services/remote/SymbolsProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,9 +9,9 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf import channel -from tcf.services import symbols -from tcf.channel.Command import Command +from .. import symbols +from ... import channel +from ...channel.Command import Command class Context(symbols.Symbol): diff --git a/python/src/tcf/services/remote/SysMonitorProxy.py b/python/src/tcf/services/remote/SysMonitorProxy.py index 7d9b2835c..9e2833fd5 100644 --- a/python/src/tcf/services/remote/SysMonitorProxy.py +++ b/python/src/tcf/services/remote/SysMonitorProxy.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. # * All rights reserved. self program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies self distribution, and is available at @@ -7,10 +7,11 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** + +from .. import sysmonitor +from ...channel.Command import Command -from tcf.services import sysmonitor -from tcf.channel.Command import Command class SysMonitorProxy(sysmonitor.SysMonitorService): def __init__(self, channel): @@ -19,9 +20,14 @@ class SysMonitorProxy(sysmonitor.SysMonitorService): def getChildren(self, parent_context_id, done): done = self._makeCallback(done) service = self + class GetChildrenCommand(Command): def __init__(self): - super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,)) + super(GetChildrenCommand, self).__init__(service.channel, + service, + "getChildren", + (parent_context_id,)) + def done(self, error, args): contexts = None if not error: @@ -31,27 +37,37 @@ class SysMonitorProxy(sysmonitor.SysMonitorService): done.doneGetChildren(self.token, error, contexts) return GetChildrenCommand().token - def getContext(self, id, done): + def getContext(self, contextID, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): - super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,)) + super(GetContextCommand, self).__init__(service.channel, + service, "getContext", + (contextID,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = sysmonitor.SysMonitorContext(args[1]) + if args[1]: + ctx = sysmonitor.SysMonitorContext(args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token - def getCommandLine(self, id, done): + def getCommandLine(self, contextID, done): done = self._makeCallback(done) service = self + class GetCommandLineCommand(Command): def __init__(self): - super(GetCommandLineCommand, self).__init__(service.channel, service, "getCommandLine", (id,)) + super(GetCommandLineCommand, self).__init__(service.channel, + service, + "getCommandLine", + (contextID,)) + def done(self, error, args): arr = None if not error: @@ -61,12 +77,17 @@ class SysMonitorProxy(sysmonitor.SysMonitorService): done.doneGetCommandLine(self.token, error, arr) return GetCommandLineCommand().token - def getEnvironment(self, id, done): + def getEnvironment(self, contextID, done): done = self._makeCallback(done) service = self + class GetEnvironmentCommand(Command): def __init__(self): - super(GetEnvironmentCommand, self).__init__(service.channel, service, "getEnvironment", (id,)) + super(GetEnvironmentCommand, self).__init__(service.channel, + service, + "getEnvironment", + (contextID,)) + def done(self, error, args): arr = None if not error: diff --git a/python/src/tcf/services/remote/TerminalsProxy.py b/python/src/tcf/services/remote/TerminalsProxy.py index 08d986eeb..f3e3d275a 100644 --- a/python/src/tcf/services/remote/TerminalsProxy.py +++ b/python/src/tcf/services/remote/TerminalsProxy.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,9 +9,10 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf.services import terminals -from tcf import channel -from tcf.channel.Command import Command +from .. import terminals +from ... import channel +from ...channel.Command import Command + class TerminalContext(terminals.TerminalContext): def __init__(self, service, props): @@ -22,10 +23,12 @@ class TerminalContext(terminals.TerminalContext): service = self.service done = service._makeCallback(done) context_id = self.getID() + class ExitCommand(Command): def __init__(self): super(ExitCommand, self).__init__( service.channel, service, "exit", (context_id,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -39,43 +42,57 @@ class TerminalsProxy(terminals.TerminalsService): self.channel = channel self.listeners = {} - def getContext(self, id, done): + def getContext(self, contextID, done): done = self._makeCallback(done) service = self + class GetContextCommand(Command): def __init__(self): super(GetContextCommand, self).__init__( - service.channel, service, "getContext", (id,)) + service.channel, service, "getContext", (contextID,)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = TerminalContext(service, args[1]) + if args[1]: + ctx = TerminalContext(service, args[1]) done.doneGetContext(self.token, error, ctx) return GetContextCommand().token def launch(self, terminal_type, encoding, environment, done): done = self._makeCallback(done) service = self + class LaunchCommand(Command): def __init__(self): - super(LaunchCommand, self).__init__(service.channel, service, "launch", (terminal_type, encoding, environment)) + super(LaunchCommand, self).__init__(service.channel, service, + "launch", + (terminal_type, encoding, + environment)) + def done(self, error, args): ctx = None if not error: assert len(args) == 2 error = self.toError(args[0]) - if args[1]: ctx = TerminalContext(service, args[1]) + if args[1]: + ctx = TerminalContext(service, args[1]) done.doneLaunch(self.token, error, ctx) return LaunchCommand().token def setWinSize(self, context_id, newWidth, newHeight, done): done = self._makeCallback(done) service = self + class SetWinSizeCommand(Command): def __init__(self): - super(SetWinSizeCommand, self).__init__(service.channel, service, "setWinSize", (context_id, newWidth, newHeight)) + super(SetWinSizeCommand, self).__init__(service.channel, + service, "setWinSize", + (context_id, newWidth, + newHeight)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -86,9 +103,12 @@ class TerminalsProxy(terminals.TerminalsService): def exit(self, context_id, done): done = self._makeCallback(done) service = self + class ExitCommand(Command): def __init__(self): - super(ExitCommand, self).__init__(service.channel, service, "exit", (context_id,)) + super(ExitCommand, self).__init__(service.channel, service, + "exit", (context_id,)) + def done(self, error, args): if not error: assert len(args) == 1 @@ -103,13 +123,15 @@ class TerminalsProxy(terminals.TerminalsService): def removeListener(self, listener): l = self.listeners.pop(listener, None) - if l: self.channel.removeEventListener(self, l) + if l: + self.channel.removeEventListener(self, l) class ChannelEventListener(channel.EventListener): def __init__(self, service, listener): self.service = service self.listener = listener + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -120,6 +142,6 @@ class ChannelEventListener(channel.EventListener): assert len(args) == 3 self.listener.winSizeChanged(args[0], args[1], args[2]) else: - raise IOError("Terminals service: unknown event: " + name); + raise IOError("Terminals service: unknown event: " + name) except Exception as x: self.service.channel.terminate(x) diff --git a/python/src/tcf/services/runcontrol.py b/python/src/tcf/services/runcontrol.py index c2ee7f2c6..e488715bb 100644 --- a/python/src/tcf/services/runcontrol.py +++ b/python/src/tcf/services/runcontrol.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,7 +9,7 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -from tcf import services +from .. import services NAME = "RunControl" diff --git a/python/src/tcf/services/stacktrace.py b/python/src/tcf/services/stacktrace.py index 027731fb2..682a5c51c 100644 --- a/python/src/tcf/services/stacktrace.py +++ b/python/src/tcf/services/stacktrace.py @@ -1,5 +1,5 @@ #****************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,7 +9,7 @@ # * Wind River Systems - initial API and implementation #****************************************************************************** -from tcf import services +from .. import services NAME = "StackTrace" diff --git a/python/src/tcf/services/streams.py b/python/src/tcf/services/streams.py index 6e92054e2..89068a9e3 100644 --- a/python/src/tcf/services/streams.py +++ b/python/src/tcf/services/streams.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -24,7 +24,7 @@ The service supports: delaying 'read' and 'write' commands. """ -from tcf import services +from .. import services NAME = "Streams" diff --git a/python/src/tcf/services/symbols.py b/python/src/tcf/services/symbols.py index 38bc95683..0320e2bd4 100644 --- a/python/src/tcf/services/symbols.py +++ b/python/src/tcf/services/symbols.py @@ -1,5 +1,5 @@ #****************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -9,34 +9,34 @@ # * Wind River Systems - initial API and implementation #****************************************************************************** -from tcf import services +from .. import services # Service name. NAME = "Symbols" class SymbolClass: - unknown = 0 # unknown symbol class - value = 1 # constant value - reference = 2 # variable data object - function = 3 # function body - type = 4 # a type @ReservedAssignment - comp_unit = 5 # a compilation unit - block = 6 # a block of code - namespace = 7 # a namespace + unknown = 0 # unknown symbol class + value = 1 # constant value + reference = 2 # variable data object + function = 3 # function body + type = 4 # a type @ReservedAssignment + comp_unit = 5 # a compilation unit + block = 6 # a block of code + namespace = 7 # a namespace class TypeClass: - unknown = 0 # unknown type class - cardinal = 1 # unsigned integer - integer = 2 # signed integer - real = 3 # float, double - pointer = 4 # pointer to anything. - array = 5 # array of anything. - composite = 6 # struct, union, or class. - enumeration = 7 # enumeration type. - function = 8 # function type. - member_ptr = 9 # a pointer on member type + unknown = 0 # unknown type class + cardinal = 1 # unsigned integer + integer = 2 # signed integer + real = 3 # float, double + pointer = 4 # pointer to anything. + array = 5 # array of anything. + composite = 6 # struct, union, or class. + enumeration = 7 # enumeration type. + function = 8 # function type. + member_ptr = 9 # a pointer on member type SYM_FLAG_PARAMETER = 0x000001 SYM_FLAG_TYPEDEF = 0x000002 diff --git a/python/src/tcf/services/sysmonitor.py b/python/src/tcf/services/sysmonitor.py index 078a6a4a5..ff8b5a865 100644 --- a/python/src/tcf/services/sysmonitor.py +++ b/python/src/tcf/services/sysmonitor.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -20,7 +20,7 @@ provide functionality similar to Unix 'top' utility or Windows 'Task Manager'. """ -from tcf import services +from .. import services NAME = "SysMonitor" diff --git a/python/src/tcf/services/terminals.py b/python/src/tcf/services/terminals.py index 51bd51aeb..e662fd006 100644 --- a/python/src/tcf/services/terminals.py +++ b/python/src/tcf/services/terminals.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -13,7 +13,7 @@ ITerminalsService allows to launch a new terminal on the remote target system. """ -from tcf import services +from .. import services # This service name, as it appears on the wire - a TCF name of the service. NAME = "Terminals" diff --git a/python/src/tcf/shell.py b/python/src/tcf/shell.py index ea7f1f177..d868b60ed 100644 --- a/python/src/tcf/shell.py +++ b/python/src/tcf/shell.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,18 +7,19 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** """ -Simple interactive shell for TCF. This is basically a Python interpreter with a few -TCF extensions. +Simple interactive shell for TCF. This is basically a Python interpreter with +a few TCF extensions. Usage: python -m tcf.shell Commands: peers - Print discovered peers - connect(params) - Connect to TCF peer, params = "<protocol>:<host>:<port>" + connect(params) - Connect to TCF peer, params = + "<protocol>:<host>:<port>" cmd.<service>.<command<(args) - Send command to remote service and return result disconnect - Disconnect from peer @@ -29,27 +30,37 @@ Commands: - Stop recording for service or for all services """ -import code, sys, os +import code +import os +import sys + + try: import tcf except ImportError: - # add current dir to path - sys.path.insert(0, os.getcwd()) + # add parent dir to path + sys.path.insert(0, os.path.dirname(os.getcwd())) import tcf + from tcf.util import sync, event from tcf import protocol, channel + class print_peers: "Print list of discovered peers" def __call__(self): return tcf.peers() + def __repr__(self): peers = tcf.peers() - return '\n'.join(map(lambda p: "%s, %s" % (p.getID(), p.getName()), peers.values())) + return '\n'.join(map(lambda p: "%s, %s" % (p.getID(), p.getName()), + peers.values())) -class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, channel.ChannelListener): + +class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, + channel.ChannelListener): def __init__(self): - locals = { + locals = { # @ReservedAssignment "connect" : tcf.connect, "peers" : print_peers() } @@ -57,10 +68,11 @@ class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, channel.Chann protocol.startDiscovery() protocol.invokeAndWait(protocol.addChannelOpenListener, self) code.InteractiveConsole.__init__(self, locals) + def interact(self, banner=None): try: try: - ps1 = sys.ps1 #@UndefinedVariable + ps1 = sys.ps1 # @UndefinedVariable except AttributeError: ps1 = None sys.ps1 = "tcf> " @@ -73,6 +85,7 @@ class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, channel.Chann protocol.invokeLater(protocol.removeChannelOpenListener, self) protocol.shutdownDiscovery() protocol.getEventQueue().shutdown() + def onChannelOpen(self, channel): wrapper = sync.DispatchWrapper(channel) self.locals["channel"] = wrapper @@ -81,6 +94,7 @@ class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, channel.Chann self.locals["events"] = event.EventRecorder(channel) protocol.invokeAndWait(protocol.removeChannelOpenListener, self) wrapper.addChannelListener(self) + def onChannelClosed(self, error): del self.locals["channel"] del self.locals["cmd"] @@ -88,10 +102,11 @@ class Shell(code.InteractiveConsole, protocol.ChannelOpenListener, channel.Chann del self.locals["events"] protocol.addChannelOpenListener(self) + def interact(): try: # enable commandline editing if available - import readline #@UnusedImport + import readline # @UnusedImport except ImportError: pass shell = Shell() diff --git a/python/src/tcf/tests/BasicTests.py b/python/src/tcf/tests/BasicTests.py index 338b104a8..2e4624224 100644 --- a/python/src/tcf/tests/BasicTests.py +++ b/python/src/tcf/tests/BasicTests.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -14,6 +14,7 @@ import time import threading import atexit import tcf + from tcf import protocol, channel, errors from tcf.util import sync @@ -40,7 +41,7 @@ def test(): global _services protocol.startEventQueue() atexit.register(protocol.getEventQueue().shutdown) - #testTimer() + # testTimer() try: c = tcf.connect("TCP:127.0.0.1:1534") except Exception as e: diff --git a/python/src/tcf/transport.py b/python/src/tcf/transport.py index ddfc5d122..cab35dfb9 100644 --- a/python/src/tcf/transport.py +++ b/python/src/tcf/transport.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,29 +7,33 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import threading -import protocol, channel -from tcf.services import locator + +from . import protocol, channel +from .services import locator _channels = [] _listeners = [] _transports = {} _lock = threading.RLock() + class TransportProvider(object): """ - TransportProvider represents communication protocol that can be used to open TCF communication channels. + TransportProvider represents communication protocol that can be used to + open TCF communication channels. Examples of transports are: TCP/IP, RS-232, USB. - Client can implement this interface if they want to provide support for a transport that is not - supported directly by the framework. + Client can implement this interface if they want to provide support for a + transport that is not supported directly by the framework. """ def getName(self): """ - Return transport name. Same as used as peer attribute, @see IPeer.ATTR_TRANSPORT_NAME + Return transport name. Same as used as peer attribute, + @see IPeer.ATTR_TRANSPORT_NAME @return transport name. """ raise NotImplementedError("Abstract method") @@ -39,33 +43,43 @@ class TransportProvider(object): Open channel to communicate with this peer using this transport. Note: the channel can be not fully open yet when this method returns. It's state can be IChannel.STATE_OPENING. - Protocol.Listener will be called when the channel will be opened or closed. - @param peer - a IPeer object that describes remote end-point of the channel. + Protocol.Listener will be called when the channel will be opened or + closed. + @param peer - a IPeer object that describes remote end-point of the + channel. @return TCF communication channel. """ raise NotImplementedError("Abstract method") + def addTransportProvider(transport): name = transport.getName() assert name with _lock: - if _transports.get(name): raise Exception("Already registered: " + name) + if _transports.get(name): + raise Exception("Already registered: " + name) _transports[name] = transport + def removeTransportProvider(transport): name = transport.getName() assert name with _lock: - if _transports.get(name) == transport: del _transports[name] + if _transports.get(name) == transport: + del _transports[name] + def openChannel(peer): name = peer.getTransportName() - if not name: raise Exception("No transport name") + if not name: + raise Exception("No transport name") with _lock: provider = _transports.get(name) - if not provider: raise Exception("Unknown transport name: " + name) + if not provider: + raise Exception("Unknown transport name: " + name) return provider.openChannel(peer) + def channelOpened(channel): assert channel not in _channels _channels.append(channel) @@ -75,44 +89,54 @@ def channelOpened(channel): except Exception as x: protocol.log("Exception in channel listener", x) + def channelClosed(channel, error): assert channel in _channels _channels.remove(channel) + def getOpenChannels(): return _channels[:] + def addChannelOpenListener(listener): assert listener _listeners.append(listener) + def removeChannelOpenListener(listener): try: _listeners.remove(listener) except ValueError: - pass # ignore + pass # ignore + class TCPTransportProvider(TransportProvider): def getName(self): return "TCP" + def openChannel(self, p): assert self.getName() == p.getTransportName() - from tcf import peer + from . import peer attrs = p.getAttributes() host = attrs.get(peer.ATTR_IP_HOST) port = attrs.get(peer.ATTR_IP_PORT) - if not host: raise RuntimeError("No host name") + if not host: + raise RuntimeError("No host name") from channel.ChannelTCP import ChannelTCP return ChannelTCP(p, host, _parsePort(port)) + def _parsePort(port): - if not port: raise Exception("No port number") + if not port: + raise Exception("No port number") try: return int(port) except Exception: raise RuntimeError( "Invalid value of \"Port\" attribute. Must be decimal number.") + def sendEvent(service_name, event_name, data): """ Transmit TCF event message. @@ -124,16 +148,19 @@ def sendEvent(service_name, event_name, data): # Skip channels that are executing "redirect" command - STATE_OPENING if c.getState() == channel.STATE_OPEN: s = c.getLocalService(service_name) - if s: c.sendEvent(s, event_name, data) + if s: + c.sendEvent(s, event_name, data) + def sync(done): """ - Call back after TCF messages sent by this host up to this moment are delivered - to their intended targets. This method is intended for synchronization of messages - across multiple channels. + Call back after TCF messages sent by this host up to this moment are + delivered to their intended targets. This method is intended for + synchronization of messages across multiple channels. Note: Cross channel synchronization can reduce performance and throughput. - Most clients don't need cross channel synchronization and should not call this method. + Most clients don't need cross channel synchronization and should not call + this method. @param done will be executed by dispatch thread after communication messages are delivered to corresponding targets. @@ -141,18 +168,21 @@ def sync(done): This is internal API, TCF clients should use protocol.sync(). """ tokenSet = set() + class DoneSync(locator.DoneSync): def doneSync(self, token): assert tokenSet.contains(token) tokenSet.remove(token) - if len(tokenSet) == 0: done() + if len(tokenSet) == 0: + done() done_sync = DoneSync() for c in _channels: if c.getState() == channel.STATE_OPEN: s = c.getRemoteService(locator.NAME) - if s: tokenSet.append(s.sync(done_sync)) - if len(tokenSet) == 0: protocol.invokeLater(done) + if s: + tokenSet.append(s.sync(done_sync)) + if len(tokenSet) == 0: + protocol.invokeLater(done) # initialize TCP transport addTransportProvider(TCPTransportProvider()) - diff --git a/python/src/tcf/util/__init__.py b/python/src/tcf/util/__init__.py index 29aa42bc1..e1c830ba1 100644 --- a/python/src/tcf/util/__init__.py +++ b/python/src/tcf/util/__init__.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,4 +7,4 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** diff --git a/python/src/tcf/util/cache.py b/python/src/tcf/util/cache.py index 7e33c535e..f64344ba2 100644 --- a/python/src/tcf/util/cache.py +++ b/python/src/tcf/util/cache.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,39 +7,49 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import cStringIO -from tcf import protocol, channel +from .. import protocol, channel + class DataCache(object): """ Objects of this class are used to cache TCF remote data. The cache is asynchronous state machine. The states are: - 1. Valid - cache is in sync with remote data, use getError() and getData() to get cached data - 2. Invalid - cache is out of sync, start data retrieval by calling validate() - 3. Pending - cache is waiting result of a command that was sent to remote peer + 1. Valid - cache is in sync with remote data, use getError() and getData() + to get cached data + 2. Invalid - cache is out of sync, start data retrieval by calling + validate() + 3. Pending - cache is waiting result of a command that was sent to remote + peer 4. Disposed - cache is disposed and cannot be used to store data. A cache instance can be created on any data type that needs to be cached. - Examples might be context children list, context properties, context state, memory data, - register data, symbol, variable, etc. - Clients of cache items can register for cache changes, but don't need to think about any particular events - since that is handled by the cache item itself. + Examples might be context children list, context properties, context state, + memory data, register data, symbol, variable, etc. + Clients of cache items can register for cache changes, but don't need to + think about any particular events since that is handled by the cache item + itself. A typical cache client should implement Runnable interface. The implementation of run() method should: Validate all cache items required for client task. - If anything is invalid then client should not alter any shared data structures, - should discard any intermediate results and register (wait) for changes of invalid cache instance(s) state. - When cache item state changes, client is invoked again and full validation is restarted. - Once everything is valid, client completes its task in a single dispatch cycle. + If anything is invalid then client should not alter any shared data + structures, should discard any intermediate results and register (wait) for + changes of invalid cache instance(s) state. + + When cache item state changes, client is invoked again and full validation + is restarted. + Once everything is valid, client completes its task in a single dispatch + cycle. - Note: clients should never retain copies of remote data across dispatch cycles! - Such data would get out of sync and compromise data consistency. - All remote data and everything derived from remote data should be kept in cache items - that implement proper event handling and can keep data consistent across dispatch cycles. + Note: clients should never retain copies of remote data across dispatch + cycles! Such data would get out of sync and compromise data + consistency. All remote data and everything derived from remote data + should be kept in cache items that implement proper event handling + and can keep data consistent across dispatch cycles. """ __error = None @@ -55,8 +65,10 @@ class DataCache(object): self.__waiting_list = None def post(self): - if self.__posted: return - if not self.__waiting_list: return + if self.__posted: + return + if not self.__waiting_list: + return protocol.invokeLater(self) self.__posted = True @@ -80,7 +92,8 @@ class DataCache(object): def getError(self): """ - @return error object if data retrieval ended with an error, or None if retrieval was successful. + @return error object if data retrieval ended with an error, or None if + retrieval was successful. Note: It is prohibited to call this method when cache is not valid. """ assert self.__valid @@ -97,8 +110,10 @@ class DataCache(object): def __call__(self): """ - Notify waiting clients about cache state change and remove them from wait list. - It is responsibility of clients to check if the state change was one they are waiting for. + Notify waiting clients about cache state change and remove them from + wait list. + It is responsibility of clients to check if the state change was one + they are waiting for. Clients are not intended to call this method. """ assert protocol.isDispatchThread() @@ -107,34 +122,41 @@ class DataCache(object): arr = self.__waiting_list self.__waiting_list = None for r in arr: - if isinstance(r, DataCache) and r._DataCache__posted: continue + if isinstance(r, DataCache) and r._DataCache__posted: + continue r() - if self.__waiting_list is None: self.__waiting_list = arr + if self.__waiting_list is None: + self.__waiting_list = arr def wait(self, cb): """ Add a client call-back to cache wait list. Client call-backs are activated when cache state changes. Call-backs are removed from waiting list after that. - It is responsibility of clients to check if the state change was one they are waiting for. + It is responsibility of clients to check if the state change was one + they are waiting for. @param cb - a call-back object """ assert protocol.isDispatchThread() assert not self.__disposed assert not self.__valid if cb and not self.isWaiting(cb): - if self.__waiting_list is None: self.__waiting_list = [] + if self.__waiting_list is None: + self.__waiting_list = [] self.__waiting_list.append(cb) def isWaiting(self, cb): """ - Return True if a client call-back is waiting for state changes of this cache item. + Return True if a client call-back is waiting for state changes of this + cache item. @param cb - a call-back object. @return True if 'cb' is in the wait list. """ - if not self.__waiting_list: return False + if not self.__waiting_list: + return False for r in self.__waiting_list: - if r is cb: return True + if r is cb: + return True return False def __validate(self): @@ -149,8 +171,10 @@ class DataCache(object): self.__error = None self.__data = None else: - if self._command is not None: return False - if not self.__valid and not self.startDataRetrieval(): return False + if self._command is not None: + return False + if not self.__valid and not self.startDataRetrieval(): + return False assert self.__valid assert self._command is None self.post() @@ -162,20 +186,23 @@ class DataCache(object): add a client call-back to cache wait list. Client call-backs are activated when cache state changes. Call-backs are removed from waiting list after that. - It is responsibility of clients to check if the state change was one they are waiting for. + It is responsibility of clients to check if the state change was one + they are waiting for. If the cache is valid do nothing and return True. @param cb - a call-back object (optional) @return True if the cache is already valid """ if not self.__validate(): - if cb: self.wait(cb) + if cb: + self.wait(cb) return False return True def start(self, command): """ Start cache pending state. - Pending state is when the cache is waiting for a TCF command to return results. + Pending state is when the cache is waiting for a TCF command to return + results. @param command - TCF command handle. """ assert not self.__valid @@ -188,7 +215,8 @@ class DataCache(object): End cache pending state, but not mark the cache as valid. @param command - TCF command handle. """ - if self._command is not command: return + if self._command is not command: + return assert not self.__valid self._command = None self.post() @@ -196,15 +224,18 @@ class DataCache(object): def set(self, token, error, data): """ End cache pending state and mark the cache as valid. - If 'token' != None, the data represent results from a completed command. - The data should be ignored if current cache pending command is not same as 'token'. + If 'token' != None, the data represent results from a completed + command. + The data should be ignored if current cache pending command is not same + as 'token'. It can happen if the cache was reset or canceled during data retrieval. @param token - pending command handle or None. @param error - data retrieval error or None @param data - up-to-date data object """ assert protocol.isDispatchThread() - if token and self._command is not token: return + if token and self._command is not token: + return self._command = None if not self.__disposed: assert not self.__valid @@ -218,7 +249,8 @@ class DataCache(object): def reset(self, data=None): """ - Force cache to become valid, cancel pending data retrieval if data is provided. + Force cache to become valid, cancel pending data retrieval if data is + provided. @param data - up-to-date data object (optional) """ assert protocol.isDispatchThread() @@ -253,10 +285,14 @@ class DataCache(object): def __str__(self): bf = cStringIO.StringIO() bf.write('[') - if self.__valid: bf.append("valid,") - if self.__disposed: bf.write("disposed,") - if self.__posted: bf.write("posted,") - if self.__error is not None: bf.write("error,") + if self.__valid: + bf.append("valid,") + if self.__disposed: + bf.write("disposed,") + if self.__posted: + bf.write("posted,") + if self.__error is not None: + bf.write("error,") bf.write("data=") bf.write(str(self.__data)) bf.write(']') @@ -264,7 +300,8 @@ class DataCache(object): def startDataRetrieval(self): """ - Sub-classes should override this method to implement actual data retrieval logic. + Sub-classes should override this method to implement actual data + retrieval logic. @return True is all done, False if retrieval is in progress. """ raise NotImplementedError("Abstract method") diff --git a/python/src/tcf/util/event.py b/python/src/tcf/util/event.py index 676f8c884..4c552db29 100644 --- a/python/src/tcf/util/event.py +++ b/python/src/tcf/util/event.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,14 +7,17 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** import threading -from tcf import protocol, channel + +from .. import protocol, channel + class DelegatingEventListener(channel.EventListener): def __init__(self, _callable): self._callable = _callable + def event(self, name, data): try: args = channel.fromJSONSequence(data) @@ -22,12 +25,15 @@ class DelegatingEventListener(channel.EventListener): except Exception as x: protocol.log("Error decoding event data", x) + def _print_event(service, name, *args): print "Event: %s.%s%s" % (service, name, tuple(args)) + def get_event_printer(): return DelegatingEventListener(_print_event) + class EventRecorder(object): def __init__(self, channel): self._channel = channel @@ -35,44 +41,54 @@ class EventRecorder(object): self._listeners = {} self._lock = threading.RLock() self._filter = None + def __del__(self): if self._channel.state == channel.STATE_OPEN: self.stop() + def record(self, service, enable=True): with self._lock: listener = self._listeners.get(service) if listener: if not enable: - protocol.invokeLater(self._channel.removeEventListener, service, listener) + protocol.invokeLater(self._channel.removeEventListener, + service, listener) elif enable: recorder = self + class Listener(channel.EventListener): def event(self, name, data): e = Event(service, name, data) recorder._event(e) listener = Listener() self._listeners[service] = listener - protocol.invokeLater(self._channel.addEventListener, service, listener) + protocol.invokeLater(self._channel.addEventListener, service, + listener) self._recording = enable + def stop(self, service=None): if service: self.record(service, False) else: for service in self._listeners.keys(): self.record(service, False) + def get(self): with self._lock: events = self._events self._events = [] return events + def _event(self, e): with self._lock: self._events.append(e) + def __str__(self): events = self.get() return "\n".join(map(str, events)) __repr__ = __str__ + class Event(object): def __init__(self, service, name, data): self.service = service @@ -81,6 +97,7 @@ class Event(object): self.args = channel.fromJSONSequence(data) except Exception as x: protocol.log("Error decoding event data", x) + def __str__(self): return "Event: %s.%s%s" % (self.service, self.name, tuple(self.args)) __repr__ = __str__ diff --git a/python/src/tcf/util/logging.py b/python/src/tcf/util/logging.py index 0a15b5cde..889ff3dd7 100644 --- a/python/src/tcf/util/logging.py +++ b/python/src/tcf/util/logging.py @@ -1,5 +1,5 @@ -# ******************************************************************************* -# * Copyright (c) 2011 Wind River Systems, Inc. and others. +# ***************************************************************************** +# * Copyright (c) 2011, 2013 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 @@ -7,15 +7,19 @@ # * # * Contributors: # * Wind River Systems - initial API and implementation -# ******************************************************************************* +# ***************************************************************************** "Internal utility methods used for logging/tracing." -from tcf import protocol -import locale, time, cStringIO +import cStringIO +import locale +import time + +from .. import protocol DECIMAL_DELIMITER = locale.localeconv().get('decimal_point', '.') + def getDebugTime(): """ Returns a relative timestamp in the form "seconds,milliseconds". Each @@ -31,16 +35,21 @@ def getDebugTime(): # Record the time tm = int(time.time() * 1000) seconds = (tm / 1000) % 1000 - if seconds < 100: traceBuilder.write('0') - if seconds < 10: traceBuilder.write('0') + if seconds < 100: + traceBuilder.write('0') + if seconds < 10: + traceBuilder.write('0') traceBuilder.write(str(seconds)) traceBuilder.write(DECIMAL_DELIMITER) millis = tm % 1000 - if millis < 100: traceBuilder.write('0') - if millis < 10: traceBuilder.write('0') + if millis < 100: + traceBuilder.write('0') + if millis < 10: + traceBuilder.write('0') traceBuilder.write(str(millis)) return traceBuilder.getvalue() + def trace(msg): """ Trace hooks should use this method to log a message. It prepends the diff --git a/python/src/tcf/util/sync.py b/python/src/tcf/util/sync.py index 71ed27bb6..2114febe0 100644 --- a/python/src/tcf/util/sync.py +++ b/python/src/tcf/util/sync.py @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. +# * Copyright (c) 2011, 2013 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 @@ -11,8 +11,8 @@ import threading import types -from tcf import protocol -from tcf.channel.Command import Command +from .. import protocol +from ..channel.Command import Command class DispatchWrapper(object): @@ -91,7 +91,7 @@ class CommandControl(object): class GenericCommand(Command): _result = None - def done(self, error, args): #@IgnorePep8 + def done(self, error, args): # @IgnorePep8 resultArgs = None if not error and args: # error result is usually in args[0], diff --git a/python/src/tcf/util/task.py b/python/src/tcf/util/task.py index c541dea6a..cdca94eb7 100644 --- a/python/src/tcf/util/task.py +++ b/python/src/tcf/util/task.py @@ -1,5 +1,5 @@ #****************************************************************************** -# Copyright (c) 2011 Wind River Systems, Inc. and others. +# Copyright (c) 2011, 2013 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 @@ -10,23 +10,30 @@ #****************************************************************************** import threading -from tcf import protocol, channel +from .. import protocol, channel + class Task(object): - """ - A <tt>Task</tt> is an utility class that represents the result of an asynchronous - communication over TCF framework. Methods are provided to check if the communication is - complete, to wait for its completion, and to retrieve the result of - the communication. - - Task is useful when communication is requested by a thread other then TCF dispatch thread. - If client has a global state, for example, cached remote data, multithreading should be avoided, - because it is extremely difficult to ensure absence of racing conditions or deadlocks in such environment. - Such clients should consider message driven design, see DataCache and its usage as an example. - - If a client is extending Task it should implement run() method to perform actual communications. - The run() method will be execute by TCF dispatch thread, and client code should then call either done() or - error() to indicate that task computations are complete. + """A <tt>Task</tt> is an utility class that represents the result of an + asynchronous communication over TCF framework. + + Methods are provided to check if the communication is complete, to wait for + its completion, and to retrieve the result of the communication. + + Task is useful when communication is requested by a thread other then TCF + dispatch thread. + If client has a global state, for example, cached remote data, + multithreading should be avoided, + because it is extremely difficult to ensure absence of racing conditions or + deadlocks in such environment. + Such clients should consider message driven design, see DataCache and its + usage as an example. + + If a client is extending Task it should implement run() method to perform + actual communications. + The run() method will be execute by TCF dispatch thread, and client code + should then call either done() or error() to indicate that task + computations are complete. """ __result = None __is_done = False @@ -59,6 +66,7 @@ class Task(object): 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) @@ -81,7 +89,8 @@ class Task(object): def done(self, result): with self._lock: assert protocol.isDispatchThread() - if self.__canceled: return + if self.__canceled: + return assert not self.__is_done assert not self.__error assert self.__result is None @@ -94,14 +103,16 @@ class Task(object): def error(self, error): """ Set a error and notify all threads waiting for the task to complete. - The method is supposed to be called in response to executing of run() method of this task. + The method is supposed to be called in response to executing of run() + method of this task. @param error - computation error. """ assert protocol.isDispatchThread() assert error with self._lock: - if self.__canceled: return + if self.__canceled: + return assert self.__error is None assert self.__result is None assert not self.__is_done @@ -113,7 +124,8 @@ class Task(object): def cancel(self): assert protocol.isDispatchThread() with self._lock: - if self.isDone(): return False + if self.isDone(): + return False self.__canceled = True self.__error = Exception("Canceled") if self.__channel: @@ -176,5 +188,6 @@ class Task(object): def getResult(self): return self.__result + class TimeoutException(Exception): pass |