From 1bff08320727d4526487ca1db76f602919a1a159 Mon Sep 17 00:00:00 2001 From: comrumino Date: Mon, 20 Feb 2023 21:18:53 -0600 Subject: [PATCH] Fixed #527 by releasing/notifying prior to dispatch (breaking commit 299ca141734204955c96809d6bc5f33d7f57cbcf). --- rpyc/core/protocol.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rpyc/core/protocol.py b/rpyc/core/protocol.py index 13203d4e..b7e50445 100644 --- a/rpyc/core/protocol.py +++ b/rpyc/core/protocol.py @@ -431,7 +431,7 @@ def serve(self, timeout=1, wait_for_lock=True): # serving return self._recv_event.wait(timeout.timeleft()) else: return False - # Assume the receive rlock is acquired and incremented + # Assume the receive rlock is acquired and incremented. For except/else, we release and notify of _recv_event. try: data = None # Ensure data is initialized data = self._channel.poll(timeout) and self._channel.recv() @@ -442,17 +442,16 @@ def serve(self, timeout=1, wait_for_lock=True): # serving with self._recv_event: self._recv_event.notify_all() raise - # At this point, the recvlock was acquired once, we must release once before exiting the function - if data: - # Dispatch will unbox, invoke callbacks, etc. - self._dispatch(data) + else: + # We must release once, notify, and THEN dispatch (see issue #527). self._recvlock.release() with self._recv_event: self._recv_event.notify_all() - return True - else: - self._recvlock.release() - return False + if data: + self._dispatch(data) # Dispatch will unbox, invoke callbacks, etc. + return True + else: + return False def _serve_bound(self, timeout, wait_for_lock): """Serves messages like `serve` with the added benefit of making request/reply thread bound.