Crossing thread boundary with idle function

2006-12-13 Thread Philip Boulain
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

2006-12-13 Thread Chris Vine
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

2006-12-13 Thread Philip Boulain
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

2006-12-13 Thread Chris Vine
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