GNOME Bugzilla – Bug 741450
maincontext: Iterate the NSApplication runloop on OSX
Last modified: 2018-05-24 17:20:01 UTC
Created attachment 292619 [details] [review] WIP patch See summary, and also see bug #704374 (comment 18 and following especially) for some background. We would like to have something like this in GMainContext to make sure that on OSX a maincontext running on the main thread is also iterating the runloop on that thread. With this applications and libraries - can use the GCD and the main queue unconditionally - can use other OSX APIs without worrying that nothing is iterating the main thread runloop In GStreamer this was the source of many crashes and deadlocks. We want to be able to always e.g. create a NSWindow on OSX, independent of the application being a GLib application that uses GDK, or one that does not use GDK, or a native OSX application. There are a few hacks in place for that currently[0][1] but the only reliable solution for this is by adding things to GMainContext. We also can't do the GDK hack because there is not necessarily something iterating the default main context (native applications), but we have no way of knowing if that is the case or not. In GDK this would allow to get rid of the custom main context handling, which also does not work properly according to bug #704374. Attached patch does this, and is based on the GDK code. For making use of this in GDK a bit more is needed though: GDK needs to be able to intercept native events before we send them off to the NSApp. The patch is currently WIP and still has lots of debug printfs everywhere, I just wanted to get it out there to get some feedback on the general idea already. It works for the GStreamer use cases and allows to get rid of the code in [0][1]. For this I would propose to add some kind of function that can be set on the main context for intercepting the events. Unfortunately this API would be OSX specific, and would need some kind of glib-osx (like glib-unix currently). If anybody has better ideas please let me know :) [0] http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m#n46 [1] http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/sys/osxvideo/osxvideosink.m#n74
Also note that this currently does not break GDK either, all the new code is only happening if a) a main context is acquired on the main thread and b) the poll function is the default one (g_poll). GDK would override the poll function and do its own stuff there.
Review of attachment 292619 [details] [review]: No. We will never take this approach in GLib. The only viable way to handle this is to transition GMainContext over to being based on kqueue and then put that kqueue fd into the cocoa loop. When GMainContext is iterated we iterate the cocoa loop instead and when we have an event in our loop it will dispatch back to us to handle it.
Just to clarify, this would in the end be the same approach but replacing this thread that converts a poll over multiple fds to a single event by that single kqueue fd and then using a CFFileDescriptor to inject that into the NSApplication loop. So there would need to be some get_magic_fd() method on the main context that gives you a single fd (based on kqueue, epoll, or emulated via a thread and poll?). And there would be a way override the default behaviour for iterating GMainContext, which could then iterate the NSApplication runloop on OSX. And yet another OSX specific function to replace the default (current) behaviour of the global default main context with this. Correct?
And GDK would work with all this by adding an observer for the events it cares about to the NSApp runloop... and from that observer dispatch to the main context via g_idle_add() or something to prevent recursion.
(In reply to comment #3) > Just to clarify, this would in the end be the same approach but replacing this > thread that converts a poll over multiple fds to a single event by that single > kqueue fd and then using a CFFileDescriptor to inject that into the > NSApplication loop. > > > So there would need to be some get_magic_fd() method on the main context that > gives you a single fd (based on kqueue, epoll, or emulated via a thread and > poll?). And there would be a way override the default behaviour for iterating > GMainContext, which could then iterate the NSApplication runloop on OSX. And > yet another OSX specific function to replace the default (current) behaviour of > the global default main context with this. > > > Correct? Yes. (In reply to comment #4) > And GDK would work with all this by adding an observer for the events it cares > about to the NSApp runloop... and from that observer dispatch to the main > context via g_idle_add() or something to prevent recursion. I'm not sure, but that sounds plausible. The idea, however, is that there would be far less of a distinction between NSApp dispatches and gmain dispatches than there is today, so I'm not sure that GDK would have to bother with the idle.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/971.