Skip to content

Commit 9b9c8de

Browse files
committed
fix possible race condition when creating instances with instancemode "single"
1 parent e6bfacc commit 9b9c8de

File tree

3 files changed

+10
-7
lines changed

3 files changed

+10
-7
lines changed

Pyro5/server.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ def __init__(self, host=None, port=0, unixsocket=None, nathost=None, natport=Non
249249
self._pyroInstances = {} # pyro objects for instance_mode=single (singletons, just one per daemon)
250250
self.streaming_responses = {} # stream_id -> (client, creation_timestamp, linger_timestamp, stream)
251251
self.housekeeper_lock = threading.Lock()
252+
self.create_single_instance_lock = threading.Lock()
252253
self.__mustshutdown.clear()
253254
self.methodcall_error_handler = _default_methodcall_error_handler
254255

@@ -574,12 +575,13 @@ def createInstance(clazz, creator):
574575
instance_mode, instance_creator = clazz._pyroInstancing
575576
if instance_mode == "single":
576577
# create and use one singleton instance of this class (not a global singleton, just exactly one per daemon)
577-
instance = self._pyroInstances.get(clazz)
578-
if not instance:
579-
log.debug("instancemode %s: creating new pyro object for %s", instance_mode, clazz)
580-
instance = createInstance(clazz, instance_creator)
581-
self._pyroInstances[clazz] = instance
582-
return instance
578+
with self.create_single_instance_lock:
579+
instance = self._pyroInstances.get(clazz)
580+
if not instance:
581+
log.debug("instancemode %s: creating new pyro object for %s", instance_mode, clazz)
582+
instance = createInstance(clazz, instance_creator)
583+
self._pyroInstances[clazz] = instance
584+
return instance
583585
elif instance_mode == "session":
584586
# Create and use one instance for this proxy connection
585587
# the instances are kept on the connection object.

docs/source/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Change Log
88
- added methodcall_error_handler to Daemon that allows you to provide a custom error handler,
99
which is called when an exception occurs in the method call's user code
1010
- introduced ``api.serve`` / ``server.serve`` as a replacement for the static class method ``Daemon.serveSimple``
11+
- fix possible race condition when creating instances with instancemode "single"
1112
- introduced some more type hintings
1213

1314

docs/source/servercode.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ There are three possible choices for the ``instance_mode`` parameter:
605605

606606
- ``session``: (the default) a new instance is created for every new proxy connection, and is reused for
607607
all the calls during that particular proxy session. Other proxy sessions will deal with a different instance.
608-
- ``single``: a single instance will be created and used for all method calls, regardless what proxy
608+
- ``single``: a single instance will be created and used for all method calls (for this daemon), regardless what proxy
609609
connection we're dealing with. This is the same as creating and registering a single object yourself
610610
(the old style of registering code with the deaemon). Be aware that the methods on this object can be called
611611
from separate threads concurrently.

0 commit comments

Comments
 (0)