On 2013-11-30 00:38, Dan wrote:
Hi,

I can't find any documentation(*) stating positively whether
gobject.idle_add and timeout_add are safe to call from a non-main
thread (e.g. a gstreamer message callback). Specifically,

def work(*args):
   # (1) gtk.gdk.threads_enter() ??
   self.ui.change_some_label()
   # (2) gtk.gdk.threads_leave() ??

# (3) gtk.gdk.threads_enter() ??
gobject.idle_add (work)
# (4) gtk.gdk.threads_leave() ??

Are (1)/(2) and/or (3)/(4) necessary? And for which pygtk versions
does this apply? I am targetting separately 2.12 (on an embedded
platform) and 2.24 (on the desktop).


(*) Except https://developer.gnome.org/gdk/unstable/gdk-Threads.html
which seems to be from 1999 and implies that __for gtk, not pygtk__
the g_idle_add requires both (1)/(2) and (3)/(4). I can't actually
find any recent GTK+ documentation that unambiguously resolves the
issue.

Both idle_add and timeout_add are thread safe, as are all GLib mainloop functions AFAIK. It's the GTK and GDK functions you have to be careful with. You don't need (3)/(4). You should still have (1)/(2), or "with gtk.gdk.lock:" if your version of gtk is new enough. It may be easier to create your own wrappers around idle_add and timeout_add like this:

  def _callback_wrapper(func, *args, **kw):
      gtk.gdk.threads_enter()
      try:
          return func(*args, **kw)
      finally:
          gtk.gdk.threads_leave()

  def idle_add_lock(func, *args, **kw):
      return gobject.idle_add(_callback_wrapper, func, *args, **kw)

  def timeout_add_lock(milliseconds, func, *args, **kw):
      return gobject.timeout_add(milliseconds,
                                 _callback_wrapper, func, *args, **kw)

--
Tim Evans
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to