From: Mike Bayer Date: Mon, 26 Jun 2006 04:32:34 +0000 (+0000) Subject: attempting to fix reentrant condition that can happen with Queue.Queue X-Git-Tag: rel_0_2_4~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3d88870e33bbfce83298c1ac7aa11004bae2d823;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git attempting to fix reentrant condition that can happen with Queue.Queue --- 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