[pytango] 432/483: Fix reference counting
Sandor Bodo-Merle
sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:15:09 UTC 2017
This is an automated email from the git hooks/post-receive script.
sbodomerle-guest pushed a commit to annotated tag bliss_8.10
in repository pytango.
commit 8350f9e0cc8b85a504bf5a361bf9641cff55501e
Author: coutinho <coutinho at esrf.fr>
Date: Tue Dec 16 17:21:07 2014 +0100
Fix reference counting
---
src/boost/python/server.py | 99 +++++++++++++++++++++++++++-------------------
1 file changed, 58 insertions(+), 41 deletions(-)
diff --git a/src/boost/python/server.py b/src/boost/python/server.py
index 23c577e..6a6fbcb 100644
--- a/src/boost/python/server.py
+++ b/src/boost/python/server.py
@@ -21,6 +21,7 @@ __all__ = ["DeviceMeta", "Device", "LatestDeviceImpl", "attribute",
import os
import sys
+import types
import inspect
import logging
import weakref
@@ -1169,7 +1170,8 @@ def __to_tango_type_fmt(value):
def create_tango_class(server, obj, tango_class_name=None, member_filter=None):
- log = logging.getLogger("PyTango.Server")
+ slog = server.server_instance.replace("/", ".")
+ log = logging.getLogger("PyTango.Server." + slog)
obj_klass = obj.__class__
obj_klass_name = obj_klass.__name__
@@ -1184,13 +1186,21 @@ def create_tango_class(server, obj, tango_class_name=None, member_filter=None):
def __init__(self, tango_class_obj, name):
Device.__init__(self, tango_class_obj, name)
- self.__tango_obj = server.get_tango_object(self.get_name())
- self.__tango_obj.device = self
+ tango_object = server.get_tango_object(self.get_name())
+ self.__tango_object = weakref.ref(tango_object)
def init_device(self):
Device.init_device(self)
self.set_state(DevState.ON)
+ @property
+ def _tango_object(self):
+ return self.__tango_object()
+
+ @property
+ def _object(self):
+ return self._tango_object._object
+
DeviceDispatcher.__name__ = tango_class_name
DeviceDispatcherClass = DeviceDispatcher.TangoClassClass
@@ -1211,25 +1221,23 @@ def create_tango_class(server, obj, tango_class_name=None, member_filter=None):
log.debug("filtered out %s from %s", name, tango_class_name)
continue
if inspect.isroutine(member):
- func = member
- func_name = name
- def _command(obj, func_name, param):
- #server = Server()
- runner = server.runner
+ def _command(dev, param, func_name=None):
+ obj = dev._object
args, kwargs = loads(*param)
f = getattr(obj, func_name)
- if runner:
- result = runner.execute(f, *args, **kwargs)
+ if server.runner:
+ result = server.runner.execute(f, *args, **kwargs)
else:
result = f(*args, **kwargs)
return server.dumps(result)
- cmd = functools.partial(_command, obj, func_name)
+ cmd = functools.partial(_command, func_name=name)
cmd.__name__ = name
- doc = func.__doc__
+ doc = member.__doc__
if doc is None:
doc = ""
cmd.__doc__ = doc
- setattr(DeviceDispatcher, func_name, cmd)
+ cmd = types.MethodType(cmd, None, DeviceDispatcher)
+ setattr(DeviceDispatcher, name, cmd)
DeviceDispatcherClass.cmd_list[name] = \
[[CmdArgType.DevEncoded, doc],
[CmdArgType.DevEncoded, ""]]
@@ -1250,33 +1258,33 @@ def create_tango_class(server, obj, tango_class_name=None, member_filter=None):
def read(dev, attr):
name = attr.get_name()
if server.runner:
- value = server.runner.execute(getattr, obj, name)
+ value = server.runner.execute(getattr, dev._object, name)
else:
- value = getattr(obj, name)
+ value = getattr(dev._object, name)
attr.set_value(*server.dumps(value))
def write(dev, attr):
name = attr.get_name()
value = attr.get_write_value()
value = loads(*value)
if server.runner:
- server.runner.execute(setattr, obj, name, value)
+ server.runner.execute(setattr, dev._object, name, value)
else:
- setattr(obj, name, value)
+ setattr(dev._object, name, value)
else:
def read(dev, attr):
name = attr.get_name()
if server.runner:
- value = server.runner.execute(getattr, obj, name)
+ value = server.runner.execute(getattr, dev._object, name)
else:
- value = getattr(obj, name)
+ value = getattr(dev._object, name)
attr.set_value(value)
def write(dev, attr):
name = attr.get_name()
value = attr.get_write_value()
if server.runner:
- server.runner.execute(setattr, obj, name, value)
+ server.runner.execute(setattr, dev._object, name, value)
else:
- setattr(obj, name, value)
+ setattr(dev._object, name, value)
read.__name__ = "_read_" + name
setattr(DeviceDispatcher, read.__name__, read)
@@ -1302,32 +1310,36 @@ class Server:
PreInitPhase = Phase1
PostInitPhase = Phase2
- class TangoObject:
+ class TangoObjectAdapter:
- def __init__(self, obj, full_name, alias=None,
+ def __init__(self, server, obj, full_name, alias=None,
tango_class_name=None):
+ self.__server = weakref.ref(server)
self.full_name = full_name
self.alias = alias
self.class_name = obj.__class__.__name__
if tango_class_name is None:
tango_class_name = self.class_name
self.tango_class_name = tango_class_name
- self.__obj = weakref.ref(obj)
- self.__device = None
+ self.__object = weakref.ref(obj, self.__onObjectDeleted)
- @property
- def device(self):
- if self.__device is None:
- return None
- return self.__device()
+ def __onObjectDeleted(self, object_weak):
+ self.__object = None
+ server = self._server
+ server.log.info("object deleted %s(%s)", self.class_name,
+ self.full_name)
+ server.unregister_object(self.full_name)
- @device.setter
- def device(self, dev):
- self.__device = weakref.ref(dev)
+ @property
+ def _server(self):
+ return self.__server()
@property
- def obj(self):
- return self.__obj()
+ def _object(self):
+ obj = self.__object
+ if obj is None:
+ return None
+ return obj()
def __init__(self, server_name, server_type=None, port=None,
event_loop_callback=None, init_callbacks=None,
@@ -1606,6 +1618,11 @@ class Server:
"(i.e. after server_init)")
self.__tango_classes.append(klass)
+ def unregister_object(self, name):
+ del self.__objects[name.lower()]
+ if self._phase > Server.Phase1:
+ util.delete_device(name)
+
def register_object(self, obj, name, tango_class_name=None,
member_filter=None):
"""
@@ -1622,20 +1639,20 @@ class Server:
else:
raise ValueError("Invalid name")
- tango_class_name = tango_class_name or obj.__class__.__name__
- tango_class = self.get_tango_class(tango_class_name)
+ class_name = tango_class_name or obj.__class__.__name__
+ tango_class = self.get_tango_class(class_name)
if tango_class is None:
- tango_class = create_tango_class(self, obj, tango_class_name,
+ tango_class = create_tango_class(self, obj, class_name,
member_filter=member_filter)
self.register_tango_class(tango_class)
- tango_object = self.TangoObject(obj, full_name, alias,
- tango_class_name=tango_class_name)
+ tango_object = self.TangoObjectAdapter(self, obj, full_name, alias,
+ tango_class_name=class_name)
self.__objects[full_name.lower()] = tango_object
if self._phase > Server.Phase1:
util = self.tango_util
- util.create_device(tango_class_name, name)
+ util.create_device(class_name, name)
return tango_object
def run(self, timeout=None):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git
More information about the debian-science-commits
mailing list