From 1a53eaeed901f3c789ebdb867b73996ccac608c3 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Sun, 25 Jul 2010 15:00:37 +0100 Subject: 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. --- nova/process.py | 13 ++++++------- nova/tests/process_unittest.py | 7 +++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/nova/process.py b/nova/process.py index d3558ed2e..8ecef1584 100644 --- a/nova/process.py +++ b/nova/process.py @@ -205,13 +205,12 @@ class ProcessPool(object): self._pool.release() return rv -class SharedPool(ProcessPool): - _instance = None - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super(SharedPool, cls).__new__( - cls, *args, **kwargs) - return cls._instance +_instance = None +def SharedPool(): + global _instance + if _instance is None: + _instance = ProcessPool() + return _instance def simple_execute(cmd, **kwargs): return SharedPool().simple_execute(cmd, **kwargs) diff --git a/nova/tests/process_unittest.py b/nova/tests/process_unittest.py index 1c15b69a0..c96bb5913 100644 --- a/nova/tests/process_unittest.py +++ b/nova/tests/process_unittest.py @@ -120,3 +120,10 @@ class ProcessTestCase(test.TrialTestCase): pool2 = process.SharedPool() 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 -- cgit