Skip to content

Commit

Permalink
fixed refcount leakage when unboxing from cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Amir Miron authored and Amir Miron committed Sep 1, 2016
1 parent 1211fd1 commit 2a592a5
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
20 changes: 11 additions & 9 deletions rpyc/core/netref.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__',
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 5 additions & 1 deletion rpyc/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 2a592a5

Please sign in to comment.