Re: libseed-list threads and closures



.. chop...
> I made a simple module that creates the context before it starts the 
> thread, and when the thread ends it defers the cleanup to the mainloop. 
> Seems to work fine! See attached code.

Just wondering how this should be implemented.. - as it appears to work as you say..
If someone else looks at the API and finds GLib.thread_create[_full] and tries to use it.

Rather than finding the bugs you found, it should really sort out the mess for you.
eg. in
engine.c: seed_gobject_define_property_from_function_info

// handle special cases....
char* ns = g_base_info_namespace(info)
if (!g_strcmp(ns, "GLib") &&  !g_strcmp(name, "thread_create")) ) {
    set_object_set_property(ctx, object, name, seed_glib_thread_create);
    return;
}
- and implement all our 'GLib' fixes in a seed-glib.c file?


> (I plan to expand this with functions to defer functions to the 
> mainloop, and to handle locks and async queues (unless we fix the real 
> GAsyncQueue binding) and stuff like that..)
> 
> Perhaps seed_handle_closure() should be modified to defer the 
> JSGlobalContextRelease() to the mainloop like this, just in case the 
> closure is another thread?
> 
> BTW: seed_handle_closure() makes a call to 
> seed_prepare_global_context(), which is quite expensive since it parses 
> Seed.js and stuff like that. Is this really needed? The closure will 
> already be lexically bound where you defined the javascript function, 
> right? At least this seems to be the case: in the attached module, I 
> don't prepare the context, but the thread can still access outer variables.

Perhaps that should do something like
if (seed_object_get_property (ctx, global, "Seed") == seed_obj_ref) {
  return;
}

In theory you are right - the scope should all be set up, but rather than fail horibly if that assumption is wrong somewhere, it's probably easier just to do a small check..

Regards
Alan


> 
> /Jonatan
> 
> > Looks like an extension might be the way to go on this one..
> >
> > Regards
> > Alan
> >
> > On Wednesday, August 04, 2010 05:18 AM, Jonatan Liljedahl wrote:
> >> From the JSCore API docs:
> >>
> >> "JS_EXPORT JSContextGroupRef JSContextGroupCreate()
> >>
> >> A JSContextGroup associates JavaScript contexts with one another.
> >> Contexts in the same group may share and exchange JavaScript objects.
> >> Sharing and/or exchanging JavaScript objects between contexts in
> >> different groups will produce undefined behavior. When objects from
> >> the same context group are used in multiple threads, explicit
> >> synchronization is required."
> >>
> >> Of course script-side variables need to be explicitly locked if used
> >> by more than one thread, but perhaps something need to have locks
> >> around it also on the C-side?
> >>
> >> /Jonatan
> >>
> >> On 08/03/2010 09:12 PM, Jonatan Liljedahl wrote:
> >>> Commenting out JSGlobalContextRelease ((JSGlobalContextRef) ctx) at the
> >>> end of seed_handle_closure() in seed-closure.c makes the problem "go
> >>> away", but of course leaves the ctx in the land of forgotten pointers...
> >>>
> >>> So, is the problem that the ctx is released before the thread exits, or
> >>> that it's release before any nested functions inside the thread finishes
> >>> (like callbacks passed to idle_add or timeout_add), or both?
> >>>
> >>> If I understand correctly, the ctx *should* be alive as long as the
> >>> thread exists, since the ctx is created before the javascript thread
> >>> function is called and released after it has returned. But! I still get
> >>> a crash on JSGlobalContextRelease() with just a simple print() or "var x
> >>> = 2*34" in the thread. (no nested callbacks involved)
> >>>
> >>> Also, I guess this means that seed_handle_closure() is called from the
> >>> thread and not from main? That brings the question, is
> >>> seed_handle_closure() threadsafe?
> >>>
> >>> /Jonatan
> >>>
> >>>
> >>> On 08/02/2010 03:15 PM, Jonatan Liljedahl wrote:
> >>>> Any ideas on this? I'm stuck.. Hoping someone with more insight in
> >>>> closures and gobject-introspection might help.
> >>>>
> >>>> /Jonatan
> >>>>
> >>>> On 07/28/2010 04:06 PM, Jonatan Liljedahl wrote:
> >>>>> This simple code crashes (output and stacktrace at the end of this
> >>>>> mail). I don't see why it shouldn't work. GLib.idle_add() is the
> >>>>> recommended way to defer stuff from a thread to the mainloop and I've
> >>>>> used it several times in C code.
> >>>>>
> >>>>> Seems to be a problem with closures, threads and the garbage
> >>>>> collector?
> >>>>>
> >>>>> /////////// thread_bugs.js ////////////
> >>>>> var Gtk = imports.gi.Gtk;
> >>>>> Gtk.init(0,0);
> >>>>>
> >>>>> var w = new Gtk.Window({border_width: 20});
> >>>>> var b = new Gtk.Button({label: "Foo"});
> >>>>> w.add(b);
> >>>>> w.show_all();
> >>>>>
> >>>>> b.signal.clicked.connect(function() {
> >>>>> print("Clicked");
> >>>>> GLib.thread_create_full(function() {
> >>>>> print("Thread start");
> >>>>> var i=0;
> >>>>> var x=1.3;
> >>>>> for(i=0;i<9999999;i++) {
> >>>>> x *= 1.000004;
> >>>>> };
> >>>>> print(x);
> >>>>> print("Dispatch to mainloop");
> >>>>> GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,function() {
> >>>>> print("In mainloop");
> >>>>> b.label = "Bar"+x;
> >>>>> return false;
> >>>>> });
> >>>>> },null,0,true);
> >>>>> });
> >>>>>
> >>>>> Gtk.main();
> >>>>> //////////// EOF /////////////
> >> _______________________________________________
> >> libseed-list mailing list
> >> libseed-list gnome org
> >> http://mail.gnome.org/mailman/listinfo/libseed-list



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