Merge "Fix race condition in eventletutils Event"
This commit is contained in:
commit
7e429593b9
|
@ -4,6 +4,7 @@ bandit==1.4.0
|
|||
coverage==4.0
|
||||
ddt==1.0.1
|
||||
debtcollector==1.2.0
|
||||
eventlet==0.18.2
|
||||
extras==1.0.0
|
||||
fixtures==3.0.0
|
||||
flake8==2.5.5
|
||||
|
|
|
@ -24,6 +24,8 @@ import threading
|
|||
import warnings
|
||||
|
||||
from oslo_utils import importutils
|
||||
from oslo_utils import timeutils
|
||||
|
||||
|
||||
# These may or may not exist; so carefully import them if we can...
|
||||
_eventlet = importutils.try_import('eventlet')
|
||||
|
@ -151,8 +153,11 @@ class EventletEvent(object):
|
|||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
old_event = getattr(self, "_event", None)
|
||||
self._set = False
|
||||
self._event = _eventlet.event.Event()
|
||||
if old_event is not None:
|
||||
old_event.send(True)
|
||||
|
||||
def is_set(self):
|
||||
return self._set
|
||||
|
@ -167,9 +172,15 @@ class EventletEvent(object):
|
|||
self._event.send(True)
|
||||
|
||||
def wait(self, timeout=None):
|
||||
with _eventlet.timeout.Timeout(timeout, False):
|
||||
self._event.wait()
|
||||
return self.is_set()
|
||||
with timeutils.StopWatch(timeout) as sw:
|
||||
while True:
|
||||
event = self._event
|
||||
with _eventlet.timeout.Timeout(sw.leftover(return_none=True),
|
||||
False):
|
||||
event.wait()
|
||||
if event is not self._event:
|
||||
continue
|
||||
return self.is_set()
|
||||
|
||||
|
||||
def Event():
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
import threading
|
||||
import warnings
|
||||
|
||||
import eventlet
|
||||
from eventlet import greenthread
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
@ -150,3 +152,52 @@ class EventletUtilsTest(test_base.BaseTestCase):
|
|||
self.assertEqual(0, mock_eventlet.event.Event().reset.call_count)
|
||||
e_event.set()
|
||||
self.assertEqual(1, mock_eventlet.event.Event().reset.call_count)
|
||||
|
||||
def test_event_no_timeout(self):
|
||||
event = eventletutils.EventletEvent()
|
||||
|
||||
def thread_a():
|
||||
self.assertTrue(event.wait())
|
||||
|
||||
a = greenthread.spawn(thread_a)
|
||||
|
||||
with eventlet.timeout.Timeout(0.5, False):
|
||||
a.wait()
|
||||
self.fail('wait() timed out')
|
||||
|
||||
def test_event_race(self):
|
||||
event = eventletutils.EventletEvent()
|
||||
|
||||
def thread_a():
|
||||
self.assertTrue(event.wait(2))
|
||||
|
||||
a = greenthread.spawn(thread_a)
|
||||
|
||||
def thread_b():
|
||||
eventlet.sleep(0.1)
|
||||
event.clear()
|
||||
event.set()
|
||||
a.wait()
|
||||
|
||||
b = greenthread.spawn(thread_b)
|
||||
with eventlet.timeout.Timeout(0.5):
|
||||
b.wait()
|
||||
|
||||
def test_event_clear_timeout(self):
|
||||
event = eventletutils.EventletEvent()
|
||||
|
||||
def thread_a():
|
||||
self.assertFalse(event.wait(0.5))
|
||||
|
||||
a = greenthread.spawn(thread_a)
|
||||
|
||||
def thread_b():
|
||||
eventlet.sleep(0.1)
|
||||
event.clear()
|
||||
eventlet.sleep(0.1)
|
||||
event.clear()
|
||||
a.wait()
|
||||
|
||||
b = greenthread.spawn(thread_b)
|
||||
with eventlet.timeout.Timeout(0.7):
|
||||
b.wait()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
|
||||
|
||||
eventlet>=0.18.2,!=0.18.3,!=0.20.1,!=0.21.0,!=0.23.0 # MIT
|
||||
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=2.2.0 # MIT
|
||||
|
|
Loading…
Reference in New Issue