Closed wusspuss closed 3 weeks ago
Conceptually, there's no reason why it shouldn't work (after all, that's essentially what gevent does) --- provided you adhere to the rules of the event loop. It looks like this event loop is very much not reentrant. That is, if we linearize the code-flow of your example, it would be something like this:
running event loop <- implemented in C
running idle callbacks <- implemented in C
for cb in callbacks: <- implemented in C
return_value = cb() <- implemented in Python
^ Where it goes wrong
switch to another greenlet
switch right back to here
return_value = ?????
In other words, you're switching back into the main greenlet while it is still running your callback. The main greenlet expected a simple function call that returns a value, but that didn't happen. So when the main greenlet starts running again, it's in an indeterminate state --- there's no return value to be had.
Cases like this can often be handled by using more callbacks, although it's not very pretty. gevent had to do something like that to work with libuv, which is also not reentrant; we wound up with a single callback that just queues other callbacks that we execute after one iteration of the event loop.
while True:
run event loop once
for cb in callbacks:
gevent callback
collect ready greenlets; store them
run stored callbacks
I'm completely unfamiliar with the internals of the library you're working with, so this is all informed conjecture based on the function names in the stack trace.
I'm looking to resume a running greenlet from inside a GLib event loop callback (any such). To demonstrate we can use GLib.idle_add
I get '0' printed and then a segfault. Is there any possible workaround?