Re: deprecating gdk threads



hi;

On 3 August 2012 15:24, Pavel Holejsovsky <pavel holejsovsky gmail com> wrote:
> On 7/29/2012 12:09 PM, Matthias Clasen wrote:
>>
>> I've put patches for deprecating the gdk threading api at
>> https://bugzilla.gnome.org/show_bug.cgi?id=680754
>> Review appreciated.
>>
>
> I'd like to bring up the issue of how language bindings should cope with
> this.

thanks for sending the email - it's very appreciated.

I'd like to point out that all of this applies only to GTK+, given
that the GDK lock is available only (well, obviously) in GDK; this
means that any other GObject-based API will be problematic from a
thread perspective, if you're trying to access some global state.

sadly, the situation with GDK (as well as Clutter, which is not only
limited by the X11 threading model, but also by the GL one) is a bit
thorny in any case.

> Basically, the consensus from previous discussions even in language
> bindings, it is up to application authors to handle callbacks coming in
> another threads by wrapping code which needs to manipulate GTK into
> function/closure and schedule its execution via GLib.idle_add().  While this
> works generally pretty well (except that it puts the burden of knowing that
> the callback might be invoked in non-main thread to the application
> developer), there is unresolved issue with regard to destructors/finalizers.

the callback for idle_add() will be invoked in the main thread - if we
assume that the main thread is the one that called
gtk_init()/gtk_main(), which is usually the assumption under which we
generally operate. that's the whole point of using the idle_add()
function to schedule an UI update.

> Higher level languages typically use some form of garbage collection and
> thus the time when finalizers are invoked are not deterministic.  AFAIK
> python invokes finalizer callbacks from separate thread, Lua uses the same
> thread which is currently executing the Lua context, I'm not sure about
> other languages but I guess that it is similar.  In the end, this means that
> finalizers (which typically invoke g_object_unref()) can be invoked in the
> context of any thread and application/binding has generally little control
> over this.
>
> AFAICS, this does not play nice with gdk threads deprecation, because one
> way to solve the GC finalization problems was to gdk_threads_enter() before
> entering g_object_unref() call.

that would have only worked for specific classes, namely the ones that
manage GDK resources; dispose and finalize should be thread safe in
GObject, as far as GObject is concerned. using
threads_enter()/unref()/leave() would also have worked only on X11,
and assuming that the support for threading in Xlib was enabled.
otherwise, it simply was working by sheer accident.

> One way to solve this would be to put the burden on the bindings
> implementation, and force the bindings to queue g_object_unref() calls using
> g_idle_add() to be executed in the main thread.  This seems to be rather
> ineffective though.

can you explain why would it be ineffective?

keeping the GObject instance alive until needed would be fine; this
obviously assumes that there is a main loop still spinning, but if you
don't have one you can use g_main_context_invoke() to schedule the
destruction of every widget from the main context.

> Another way to solve this problem might be inside GDK itself, which might
> check whether native window disposal function needs to be transferred to the
> main thread and if yes, do it internally and transparently.  The advantages
> are:
>
> + it is done only when needed (eg only on Win32/Quartz/whatever, only when
> called from 'bad' thread, only when g_object_unref() actually results in
> window destruction)
> + much more error prone
>
> - the actual native window destroy function can be called 'asynchronously'
> from the POV of the caller.
> - someone has to implement this :-(

scheduling the destruction for the next main loop iteration could be
feasible, but it would need to be implemented as you correctly pointed
out.

ciao,
 Emmanuele.

-- 
W: http://www.emmanuelebassi.name
B: http://blogs.gnome.org/ebassi/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]