summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy McCurdy <andy@andymccurdy.com>2020-01-29 11:41:38 -0800
committerAndy McCurdy <andy@andymccurdy.com>2020-01-30 14:30:00 -0800
commit2d1b54458885a0f3d335784ed10dd1dc9ec08bb3 (patch)
tree3830bd14a9ed794ec2c8be96f914ba6691c83501
parent9df2fc459387f448dd0e9c95534db98dcdb5ad8b (diff)
downloadredis-py-2d1b54458885a0f3d335784ed10dd1dc9ec08bb3.tar.gz
move pid assignment to the last operation of the reset() method
-rwxr-xr-xredis/connection.py12
1 files changed, 11 insertions, 1 deletions
diff --git a/redis/connection.py b/redis/connection.py
index fffdc1a..4d4f405 100755
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -1094,12 +1094,22 @@ class ConnectionPool(object):
)
def reset(self):
- self.pid = os.getpid()
self._lock = threading.RLock()
self._created_connections = 0
self._available_connections = []
self._in_use_connections = set()
+ # this must be the last operation in this method. while reset() is
+ # called when holding _fork_lock, other threads in this process
+ # can call _checkpid() which compares self.pid and os.getpid() without
+ # holding any lock (for performance reasons). keeping this assignment
+ # as the last operation ensures that those other threads will also
+ # notice a pid difference and block waiting for the first thread to
+ # release _fork_lock. when each of these threads eventually acquire
+ # _fork_lock, they will notice that another thread already called
+ # reset() and they will immediately release _fork_lock and continue on.
+ self.pid = os.getpid()
+
def _checkpid(self):
# _checkpid() attempts to keep ConnectionPool fork-safe on modern
# systems. this is called by all ConnectionPool methods that