diff --git a/eventlet/pools.py b/eventlet/pools.py index c6b7728..6244c8c 100644 --- a/eventlet/pools.py +++ b/eventlet/pools.py @@ -113,10 +113,15 @@ class Pool(object): """ if self.free_items: return self.free_items.popleft() - if self.current_size < self.max_size: - created = self.create() - self.current_size += 1 + self.current_size += 1 + if self.current_size <= self.max_size: + try: + created = self.create() + except: + self.current_size -= 1 + raise return created + self.current_size -= 1 # did not create return self.channel.get() if item_impl is not None: diff --git a/tests/pools_test.py b/tests/pools_test.py index e0c6cd6..77a8d04 100644 --- a/tests/pools_test.py +++ b/tests/pools_test.py @@ -137,6 +137,26 @@ class TestIntPool(TestCase): # resize larger and assert that there are more free items pool.resize(2) self.assertEquals(pool.free(), 2) + + def test_create_contention(self): + creates = [0] + def sleep_create(): + creates[0] += 1 + eventlet.sleep() + return "slept" + + p = pools.Pool(max_size=4, create=sleep_create) + + def do_get(): + x = p.get() + self.assertEquals(x, "slept") + p.put(x) + + gp = eventlet.GreenPool() + for i in xrange(100): + gp.spawn_n(do_get) + gp.waitall() + self.assertEquals(creates[0], 4) class TestAbstract(TestCase):