Crossing thread boundary with idle function
Hullo, Short version: When GTK+ is in its main run loop, blocking on an event, is there a way to awaken/unblock it from some external thread such that it will pay attention to newly-added idle functions? Long version with context: I have a lovely multithreaded application in C++/GTKmm that I'm working on part of (oh, lucky me), but the general problem is GTK+, not the binding, so please just bear with the C++ names. :) GTK+/the UI gets a thread in this system all to itself. For various reasons, pthreads is what's being used, and GTK+ never gets to, or needs to, know that other threads exist, as _all_ GTK+ operations occur within this thread. It is, however, necessary to poke this thread occasionally from another, controlling thread. To do this, I have a notify() method, which performs a g_idle_add() [or, in GTKmm parlance, connects to Glib::signal_idle()] with a notifyInternal() function. notifyInternal() does the work it needs to in the UI thread, then returns false in order to be removed again. According to the docs, calling g_idle_add() from outside of the Glib thread is safe, so this seems like a nice, clean way to cross the thread boundary. The problem with this is that adding an idle function doesn't actually wake a blocked GTK+ main loop---the idle function won't run until some other event, such as mouse movement, does that. It /will/ run if the run(window) call is replaced with a while loop which does non-blocking iteration() calls, but this is clearly horrendously inefficient. Hence, I need to somehow need to prod the events pending condition that the GTK+ loop is waiting on. My thoughts are along the lines of giving it a synthetic event of some nature to process---hopefully at a Glib level, as the documentation has gdk_threads_enter()/leave() as necessary for multi-thread access to GDK and up, but not safe for the Win32 back-end (and, yes, this abomination is also cross-platform). Any ideas on how I can do this? Thanks in advance, Phil ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Crossing thread boundary with idle function
On Wednesday 13 December 2006 18:05, Philip Boulain wrote: Hullo, Short version: When GTK+ is in its main run loop, blocking on an event, is there a way to awaken/unblock it from some external thread such that it will pay attention to newly-added idle functions? [snip] I does that by itself. You have probably not called g_thread_init() (or Glib::thread_init()). Chris ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Crossing thread boundary with idle function
On Wed, 2006-12-13 at 21:20 +, Chris Vine wrote: On Wednesday 13 December 2006 18:05, Philip Boulain wrote: When GTK+ is in its main run loop, blocking on an event, is there a way to awaken/unblock it from some external thread such that it will pay attention to newly-added idle functions? I does that by itself. You have probably not called g_thread_init() (or Glib::thread_init()). Ah, I wondered if it was supposed to. I haven't, no; my understanding of those is that they will enable the Glib-specific threading system. I was kind of concerned about how that would interact with the fact that we're already using pthreads (various comic historic reasons). I have now added it, and that appears to work, at least for the Linux build. (If it breaks for Windows, I get to see how much teeth-gnashing can come from having to port a load of pthreads-based code over to Glib threads can cause. ;) ) (For the sake of catching stupid newbie errors which may later bite me in the posterior: the thread_init() directly precedes the Gtk::Main() construction, within the UI thread; from what I can tell, this is the correct approach.) Thanks again, Phil ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Crossing thread boundary with idle function
On Wednesday 13 December 2006 21:52, Philip Boulain wrote: On Wed, 2006-12-13 at 21:20 +, Chris Vine wrote: [snip] I does that by itself. You have probably not called g_thread_init() (or Glib::thread_init()). Ah, I wondered if it was supposed to. I haven't, no; my understanding of those is that they will enable the Glib-specific threading system. I was kind of concerned about how that would interact with the fact that we're already using pthreads (various comic historic reasons). I have now added it, and that appears to work, at least for the Linux build. (If it breaks for Windows, I get to see how much teeth-gnashing can come from having to port a load of pthreads-based code over to Glib threads can cause. ;) ) You have to call g_thread_init() before any glib functions are called, so do it early on. If you do not do that then the glib main loop (amongst other things) is not thread safe, as you have discovered. glib will use the underlying thread implementation (pthreads for Unix-like systems, and windows threads for windows). The only exception is if you are using a pthreads implementation under windows, but even that will probably work OK since the pthreads implemention will probably be a wrapper for windows threads and even if it isn't both will be using the same architecture-specific locking primitives underneath. If all else fails you can use the gthread implementation, which works on both Unix-like systems and on windows. Chris ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list