-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Callback is never called when set_result() is called on a Future #3
Comments
This is essentially the problem I wrote about here: https://blogs.gnome.org/jamesh/2019/10/07/gasyncresult-with-python-asyncio/ The basic problem is that GLib callbacks are outside of asyncio's view of what's happening on the thread. The work-around I used in that blog article was to treat these callbacks as if they were happening off-thread, and use Part of the problem is that there's a lot more entry points that require passing control back to asyncio than just |
What kind of entry points are we talking about? To me the obvious non-I/O ones are The problem I see with your But as I said above, I'm not entirely sure what entry points we're talking about, so maybe that's not feasible. |
I ran into the same issue - thanks for pointing out to the Also, as this sort of problem does not appear in gbulb, it would be worth mentioning explicitly in the differences between the two tools. |
This combines variations of fixes that have already been proposed. Fixes #1 Fixes jhenstridge#3
As it is right now, any python code that runs may modify the timeout that would be passed into the select() call. As such, we can only run a single mainloop iteration before the select() call needs to be restarted. Also, we cannot use g_source_set_ready_time, because GLib will always do a full mainloop iteration afterwards to ensure that all sources had a chance to dispatch. This is easy to work around though as we can use the prepare callback to pass the required timeout from python into the GLib main loop code. Note that with this we end up iterating the main context but we never actually run a GLib mainloop. Fixes: jhenstridge#3
As it is right now, any python code that runs may modify the timeout that would be passed into the select() call. As such, we can only run a single mainloop iteration before the select() call needs to be restarted. Also, we cannot use g_source_set_ready_time, because GLib will always do a full mainloop iteration afterwards to ensure that all sources had a chance to dispatch. This is easy to work around though as we can use the prepare callback to pass the required timeout from python into the GLib main loop code. Note that with this we end up iterating the main context but we never actually run a GLib mainloop. Fixes: jhenstridge#3
As it is right now, any python code that runs may modify the timeout that would be passed into the select() call. As such, we can only run a single mainloop iteration before the select() call needs to be restarted. Also, we cannot use g_source_set_ready_time, because GLib will always do a full mainloop iteration afterwards to ensure that all sources had a chance to dispatch. This is easy to work around though as we can use the prepare callback to pass the required timeout from python into the GLib main loop code. Note that with this we end up iterating the main context but we never actually run a GLib mainloop. Fixes: jhenstridge#3
As it is right now, any python code that runs may modify the timeout that would be passed into the select() call. As such, we can only run a single mainloop iteration before the select() call needs to be restarted. Also, we cannot use g_source_set_ready_time, because GLib will always do a full mainloop iteration afterwards to ensure that all sources had a chance to dispatch. This is easy to work around though as we can use the prepare callback to pass the required timeout from python into the GLib main loop code. Note that with this we end up iterating the main context but we never actually run a GLib mainloop. Fixes: jhenstridge#3
When code triggered by a Gtk signal calls
set_result()
on an asyncio Future object, it seems the callbacks on the Future object are not called unless something else wakes up the main loop.I've put together the following minimal example of this bug.
Expected behaviour: clicking the button should print, 'button clicked' and 'future finished', then the main loop should end.
Actual behaviour: clicking the button prints 'button clicked', then the main loop continues forever.
Tested with: Python 3.6.9, Gtk 3.22.30 and asyncio-glib 0.1.
If you uncomment the heartbeat line, so that there's a regular timed call happening, then the Future's callback is called and the main loop ends. But with that line commented, the loop does not end.
The text was updated successfully, but these errors were encountered: