Skip to content

Commit

Permalink
Fix Jython problem for dead-locking issue
Browse files Browse the repository at this point in the history
Resolves #171
  • Loading branch information
coldfix committed Jul 4, 2017
1 parent a9398f9 commit 9ae608e
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions rpyc/core/protocol.py
Expand Up @@ -153,6 +153,7 @@ def __init__(self, service, channel, config = {}, _lazy = False):
self._proxy_cache = WeakValueDict()
self._netref_classes_cache = {}
self._remote_root = None
self._send_queue = []
self._local_root = service(weakref.proxy(self))
if not _lazy:
self._init_service()
Expand Down Expand Up @@ -241,15 +242,30 @@ def _send(self, msg, seq, args):
# if so, a BaseNetref.__del__ might be called
# BaseNetref.__del__ must call asyncreq,
# which will cause a deadlock
is_gc_enabled = gc.isenabled()
gc.disable()
self._sendlock.acquire()
try:
self._channel.send(data)
finally:
self._sendlock.release()
if is_gc_enabled:
gc.enable()
# Solution:
# Add the current request to a queue and let the thread that currently
# holds the sendlock send it when it's done with its current job.
# NOTE: Atomic list operations should be thread safe,
# please call me out if they are not on all implementations!
self._send_queue.append(data)
# It is crucial to check the queue each time AFTER releasing the lock:
while self._send_queue:
if not self._sendlock.acquire(False):
# Another thread holds the lock. It will send the data after
# it's done with its current job. We can safely return.
return
try:
# Can happen if another consumer was scheduled in between
# `while` and `acquire`:
if not self._send_queue:
# Must `continue` to ensure that `send_queue` is checked
# after releasing the lock! (in case another producer is
# scheduled before `release`)
continue
data = self._send_queue.pop(0)
self._channel.send(data)
finally:
self._sendlock.release()

def _send_request(self, seq, handler, args):
self._send(consts.MSG_REQUEST, seq, (handler, self._box(args)))
Expand Down

0 comments on commit 9ae608e

Please sign in to comment.