Fix assertion "Someone released me too many times: too many tokens!" when more

than one process was running at the same time.  This
was caused by the override of SharedPool.__new__ not stopping
ProcessPool.__init__ from being run whenever process.simple_execute is called.

When __init__ ran for the second time, the DeferredSemaphore was replaced, 
and this meant that we ended up releasing a different semaphore to the one
that was acquired.
This commit is contained in:
Ewan Mellor
2010-07-25 15:00:37 +01:00
parent 0c57be0d93
commit a8fd36c867
2 changed files with 13 additions and 7 deletions

View File

@@ -205,13 +205,12 @@ class ProcessPool(object):
self._pool.release() self._pool.release()
return rv return rv
class SharedPool(ProcessPool): _instance = None
_instance = None def SharedPool():
def __new__(cls, *args, **kwargs): global _instance
if not cls._instance: if _instance is None:
cls._instance = super(SharedPool, cls).__new__( _instance = ProcessPool()
cls, *args, **kwargs) return _instance
return cls._instance
def simple_execute(cmd, **kwargs): def simple_execute(cmd, **kwargs):
return SharedPool().simple_execute(cmd, **kwargs) return SharedPool().simple_execute(cmd, **kwargs)

View File

@@ -120,3 +120,10 @@ class ProcessTestCase(test.TrialTestCase):
pool2 = process.SharedPool() pool2 = process.SharedPool()
self.assert_(id(pool1) == id(pool2)) self.assert_(id(pool1) == id(pool2))
def test_shared_pool_works_as_singleton(self):
d1 = process.simple_execute('sleep 1')
d2 = process.simple_execute('sleep 0.005')
# lp609749: would have failed with
# exceptions.AssertionError: Someone released me too many times:
# too many tokens!
return d1