From 2d1b54458885a0f3d335784ed10dd1dc9ec08bb3 Mon Sep 17 00:00:00 2001 From: Andy McCurdy Date: Wed, 29 Jan 2020 11:41:38 -0800 Subject: move pid assignment to the last operation of the reset() method --- redis/connection.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 -- cgit v1.2.1