Commit 20f0c8be authored by Denis Bilenko's avatar Denis Bilenko

event: make sure callback passed to rawlink() is always called in hub's greenlet

parent c5057e28
...@@ -10,6 +10,7 @@ class Event(object): ...@@ -10,6 +10,7 @@ class Event(object):
def __init__(self): def __init__(self):
self._links = set() self._links = set()
self._value = _NONE self._value = _NONE
self._notifier = None
def ready(self): def ready(self):
return self._value is not _NONE return self._value is not _NONE
...@@ -20,12 +21,11 @@ class Event(object): ...@@ -20,12 +21,11 @@ class Event(object):
return self._value return self._value
def rawlink(self, callback): def rawlink(self, callback):
if self._value is _NONE: if not callable(callback):
raise TypeError('Expected callable: %r' % (callback, ))
self._links.add(callback) self._links.add(callback)
else: if self.ready() and self._notifier is None:
# QQQ switch won't work as a callback! self._notifier = core.active_event(self._notify_links)
# QQQ should I schedule the callback here too, like Greenlet.rawlink does?
callback(self)
def unlink(self, callback): def unlink(self, callback):
self._links.discard(callback) self._links.discard(callback)
...@@ -38,10 +38,11 @@ class Event(object): ...@@ -38,10 +38,11 @@ class Event(object):
oldvalue = self._value oldvalue = self._value
self._value = value self._value = value
if oldvalue is _NONE: if oldvalue is _NONE:
if self._links: if self._links and self._notifier is None:
core.active_event(self._notify_links) self._notifier = core.active_event(self._notify_links)
def _notify_links(self): def _notify_links(self):
try:
assert getcurrent() is get_hub() assert getcurrent() is get_hub()
while self._links: while self._links:
link = self._links.pop() link = self._links.pop()
...@@ -54,6 +55,8 @@ class Event(object): ...@@ -54,6 +55,8 @@ class Event(object):
except: except:
pass pass
# even if g is left unscheduled, it will be deallocated because there are no more references to it # even if g is left unscheduled, it will be deallocated because there are no more references to it
finally:
self._notifier = None
def get(self, block=True, timeout=None): def get(self, block=True, timeout=None):
if self._value is not _NONE: if self._value is not _NONE:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment