From 3d88870e33bbfce83298c1ac7aa11004bae2d823 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 26 Jun 2006 04:32:34 +0000 Subject: [PATCH] attempting to fix reentrant condition that can happen with Queue.Queue --- CHANGES | 1 + lib/sqlalchemy/pool.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index 154829df8f..a20782551f 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ properly saving - fixed bug when specifying explicit module to mysql dialect - when QueuePool times out it raises a TimeoutError instead of erroneously making another connection +- attempting to fix a rare hang that can occur with Queue.Queue 0.2.3 - overhaul to mapper compilation to be deferred. this allows mappers diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index b086aae9f6..0feaf93bbb 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -15,8 +15,10 @@ import util, exceptions try: import thread + import threading except: import dummythread as thread + import dummythreading as threading proxies = {} @@ -207,6 +209,15 @@ class QueuePool(Pool): Pool.__init__(self, **params) self._creator = creator self._pool = Queue.Queue(pool_size) + + # modify the pool's mutex to be an RLock. this is because a rare condition can + # occur where a ConnectionFairy's __del__ method gets called within the get() method + # of the Queue (and then tries to do a put() within the get()), causing a re-entrant hang. + # the RLock allows the mutex to be reentrant within that case. + self._pool.mutex = threading.RLock() + self._pool.not_empty = threading.Condition(self._pool.mutex) + self._pool.not_full = threading.Condition(self._pool.mutex) + self._overflow = 0 - pool_size self._max_overflow = max_overflow self._timeout = timeout -- 2.47.3