diff --git a/rpyc/core/netref.py b/rpyc/core/netref.py index cd8db094..86c7875e 100644 --- a/rpyc/core/netref.py +++ b/rpyc/core/netref.py @@ -10,7 +10,7 @@ _local_netref_attrs = frozenset([ - '____conn__', '____oid__', '__class__', '__cmp__', '__del__', '__delattr__', + '____conn__', '____oid__', '____refcount__', '__class__', '__cmp__', '__del__', '__delattr__', '__dir__', '__doc__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__slots__', '__str__', @@ -116,18 +116,20 @@ class BaseNetref(object): """ # this is okay with py3k -- see below __metaclass__ = NetrefMetaclass - __slots__ = ["____conn__", "____oid__", "__weakref__"] + __slots__ = ["____conn__", "____oid__", "__weakref__", "____refcount__"] def __init__(self, conn, oid): self.____conn__ = conn self.____oid__ = oid + self.____refcount__ = 1 def __del__(self): - try: - asyncreq(self, consts.HANDLE_DEL) - except Exception: - # raised in a destructor, most likely on program termination, - # when the connection might have already been closed. - # it's safe to ignore all exceptions here - pass + for _ in xrange(self.____refcount__): + try: + asyncreq(self, consts.HANDLE_DEL) + except Exception: + # raised in a destructor, most likely on program termination, + # when the connection might have already been closed. + # it's safe to ignore all exceptions here + pass def __getattribute__(self, name): if name in _local_netref_attrs: diff --git a/rpyc/core/protocol.py b/rpyc/core/protocol.py index aa986f2b..c56cbbb7 100644 --- a/rpyc/core/protocol.py +++ b/rpyc/core/protocol.py @@ -298,7 +298,11 @@ def _unbox(self, package): if label == consts.LABEL_REMOTE_REF: oid, clsname, modname = value if oid in self._proxy_cache: - return self._proxy_cache[oid] + proxy = self._proxy_cache[oid] + proxy.____refcount__ += 1 # other side increased refcount on boxing, + # if I'm returning from cache instead of new object, + # must increase refcount to match + return proxy proxy = self._netref_factory(oid, clsname, modname) self._proxy_cache[oid] = proxy return proxy