]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Change state in critical section on pool.close()
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 22 Feb 2021 01:49:16 +0000 (02:49 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 12 Mar 2021 04:07:25 +0000 (05:07 +0100)
Nothing bad should happen, because what maintains the state respect the
_closed state. However because the logic is complex make it more
defensive.

psycopg3/psycopg3/pool.py

index 20b3159d58679f6d31967489356c58fa19cb9626..e3879afb0218d3694a15b06e8298d31519de5d64 100644 (file)
@@ -332,6 +332,12 @@ class ConnectionPool:
         with self._lock:
             self._closed = True
 
+            # Take waiting client and pool connections out of the state
+            waiting = list(self._waiting)
+            self._waiting.clear()
+            pool = list(self._pool)
+            self._pool.clear()
+
         # Now that the flag _closed is set, getconn will fail immediately,
         # putconn will just close the returned connection.
 
@@ -343,13 +349,11 @@ class ConnectionPool:
             self.run_task(StopWorker(self))
 
         # Signal to eventual clients in the queue that business is closed.
-        while self._waiting:
-            pos = self._waiting.popleft()
+        for pos in waiting:
             pos.fail(PoolClosed(f"the pool {self.name!r} is closed"))
 
         # Close the connections still in the pool
-        while self._pool:
-            conn = self._pool.pop()[0]
+        for conn, _ in pool:
             conn.close()
 
         # Wait for the worker threads to terminate