Commit 1971f1b4 authored by Yury Selivanov's avatar Yury Selivanov

Run spawn callbacks in Greenlet.start & start_later

parent fc42d148
...@@ -117,7 +117,6 @@ cdef class Greenlet(greenlet): ...@@ -117,7 +117,6 @@ cdef class Greenlet(greenlet):
cdef bint __start_pending(self) cdef bint __start_pending(self)
cdef bint __never_started_or_killed(self) cdef bint __never_started_or_killed(self)
cdef bint __start_completed(self) cdef bint __start_completed(self)
cdef __call_spawn_callbacks(self)
cdef __handle_death_before_start(self, tuple args) cdef __handle_death_before_start(self, tuple args)
cdef __cancel_start(self) cdef __cancel_start(self)
...@@ -150,7 +149,6 @@ cdef Waiter ...@@ -150,7 +149,6 @@ cdef Waiter
cdef wait cdef wait
cdef iwait cdef iwait
cdef reraise cdef reraise
cdef set _spawn_callbacks = None
cpdef GEVENT_CONFIG cpdef GEVENT_CONFIG
...@@ -174,3 +172,6 @@ cdef _killall(list greenlets, object exception) ...@@ -174,3 +172,6 @@ cdef _killall(list greenlets, object exception)
@cython.locals(done=list) @cython.locals(done=list)
cpdef joinall(greenlets, timeout=*, raise_error=*, count=*) cpdef joinall(greenlets, timeout=*, raise_error=*, count=*)
cdef set _spawn_callbacks = None
cdef _call_spawn_callbacks(greenlet)
...@@ -264,9 +264,6 @@ class Greenlet(greenlet): ...@@ -264,9 +264,6 @@ class Greenlet(greenlet):
self.spawn_tree_locals = None self.spawn_tree_locals = None
self._spawning_stack_frames = None self._spawning_stack_frames = None
if _spawn_callbacks is not None:
self.__call_spawn_callbacks()
@Lazy @Lazy
def spawning_stack(self): def spawning_stack(self):
# Store this in the __dict__. We don't use it from the C # Store this in the __dict__. We don't use it from the C
...@@ -347,11 +344,6 @@ class Greenlet(greenlet): ...@@ -347,11 +344,6 @@ class Greenlet(greenlet):
"Boolean indicating that the greenlet is dead and will not run again." "Boolean indicating that the greenlet is dead and will not run again."
return self.__start_cancelled_by_kill() or self.__started_but_aborted() or greenlet.dead.__get__(self) return self.__start_cancelled_by_kill() or self.__started_but_aborted() or greenlet.dead.__get__(self)
def __call_spawn_callbacks(self):
if _spawn_callbacks is not None:
for cb in _spawn_callbacks:
cb(self)
def __never_started_or_killed(self): def __never_started_or_killed(self):
return self._start_event is None return self._start_event is None
...@@ -534,8 +526,8 @@ class Greenlet(greenlet): ...@@ -534,8 +526,8 @@ class Greenlet(greenlet):
""" """
add_spawn_callback(callback) -> None add_spawn_callback(callback) -> None
Set up a *callback* to be invoked when a new :class:`Greenlet` Set up a *callback* to be invoked when :class:`Greenlet` objects
object is instantiated. are started.
The invocation order of spawn callbacks is unspecified. Adding one The invocation order of spawn callbacks is unspecified. Adding one
callback more than one time will not cause it to be called more callback more than one time will not cause it to be called more
...@@ -579,6 +571,7 @@ class Greenlet(greenlet): ...@@ -579,6 +571,7 @@ class Greenlet(greenlet):
instead of spawning a greenlet that will raise an uncaught TypeError. instead of spawning a greenlet that will raise an uncaught TypeError.
""" """
g = cls(*args, **kwargs) g = cls(*args, **kwargs)
_call_spawn_callbacks(g)
g.start() g.start()
return g return g
...@@ -602,6 +595,7 @@ class Greenlet(greenlet): ...@@ -602,6 +595,7 @@ class Greenlet(greenlet):
if cls is Greenlet and not args and 'run' not in kwargs: if cls is Greenlet and not args and 'run' not in kwargs:
raise TypeError("") raise TypeError("")
g = cls(*args, **kwargs) g = cls(*args, **kwargs)
_call_spawn_callbacks(g)
g.start_later(seconds) g.start_later(seconds)
return g return g
...@@ -934,6 +928,15 @@ def _killall(greenlets, exception): ...@@ -934,6 +928,15 @@ def _killall(greenlets, exception):
g.parent.handle_error(g, *sys_exc_info()) g.parent.handle_error(g, *sys_exc_info())
def _call_spawn_callbacks(greenlet):
if _spawn_callbacks is not None:
for cb in _spawn_callbacks:
cb(greenlet)
_spawn_callbacks = None
def killall(greenlets, exception=GreenletExit, block=True, timeout=None): def killall(greenlets, exception=GreenletExit, block=True, timeout=None):
""" """
Forceably terminate all the ``greenlets`` by causing them to raise ``exception``. Forceably terminate all the ``greenlets`` by causing them to raise ``exception``.
...@@ -983,7 +986,5 @@ def _init(): ...@@ -983,7 +986,5 @@ def _init():
_init() _init()
_spawn_callbacks = None
from gevent._util import import_c_accel from gevent._util import import_c_accel
import_c_accel(globals(), 'gevent._greenlet') import_c_accel(globals(), 'gevent._greenlet')
...@@ -704,8 +704,7 @@ class TestBasic(greentest.TestCase): ...@@ -704,8 +704,7 @@ class TestBasic(greentest.TestCase):
gr._called_test = True gr._called_test = True
gevent.Greenlet.add_spawn_callback(cb) gevent.Greenlet.add_spawn_callback(cb)
self.addCleanup(lambda: gevent.Greenlet.remove_spawn_callback(cb)) try:
g = gevent.spawn(lambda: None) g = gevent.spawn(lambda: None)
self.assertTrue(hasattr(g, '_called_test')) self.assertTrue(hasattr(g, '_called_test'))
g.join() g.join()
...@@ -714,6 +713,8 @@ class TestBasic(greentest.TestCase): ...@@ -714,6 +713,8 @@ class TestBasic(greentest.TestCase):
g = gevent.spawn(lambda: None) g = gevent.spawn(lambda: None)
self.assertFalse(hasattr(g, '_called_test')) self.assertFalse(hasattr(g, '_called_test'))
g.join() g.join()
finally:
gevent.Greenlet.remove_spawn_callback(cb)
def test_getframe_value_error(self): def test_getframe_value_error(self):
def get(): def get():
......
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