Skip to content

Commit

Permalink
Merge pull request #196 from amirmiron/netref_rc_leakage
Browse files Browse the repository at this point in the history
  • Loading branch information
coldfix committed Jul 28, 2017
2 parents 3f1cc1e + 6f3a375 commit 3195810
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 8 deletions.
9 changes: 6 additions & 3 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 @@ -43,6 +43,7 @@
_builtin_types.extend([
bytes, bytearray, type(iter(range(10))), memoryview,
])
xrange = range
else:
_builtin_types.extend([
basestring, unicode, long, xrange, type(iter(xrange(10))), file,
Expand Down Expand Up @@ -116,13 +117,15 @@ 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)
asyncreq(self, consts.HANDLE_DEL, self.___refcount__)
except Exception:
# raised in a destructor, most likely on program termination,
# when the connection might have already been closed.
Expand Down
8 changes: 6 additions & 2 deletions rpyc/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,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 Expand Up @@ -600,7 +604,7 @@ def _handle_close(self):
self._cleanup()
def _handle_getroot(self):
return self._local_root
def _handle_del(self, oid):
def _handle_del(self, oid, count=1):
self._local_objects.decref(oid)
def _handle_repr(self, oid):
return repr(self._local_objects[oid])
Expand Down
6 changes: 3 additions & 3 deletions rpyc/lib/colls.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ def add(self, obj):
def clear(self):
with self._lock:
self._dict.clear()
def decref(self, key):
def decref(self, key, count=1):
with self._lock:
slot = self._dict[key]
if slot[1] < 1:
if slot[1] < count:
del self._dict[key]
else:
slot[1] -= 1
slot[1] -= count
self._dict[key] = slot
def __getitem__(self, key):
with self._lock:
Expand Down

0 comments on commit 3195810

Please sign in to comment.