Re: [Vala] Threads and closures problem

From: JM <interflug1 gmx net>

To: vala-list <vala-list gnome org>

Subject: Re: [Vala] Threads and closures problem

Date: Thu, 14 Jan 2010 21:22:01 +0100

Hi all
Looks like closures and threads are incompatible right now.
This is the ccode generated from vala.
VALA:
Thread.create( ()=> { Thread.usleep(1000); print("in thread : %s \n",
test); }, false);
CCODE:
g_thread_create (__lambda0__gthread_func, _data1_, FALSE,
&_inner_error_);
CCODE (with owned ThreadFunc in vapi):
g_thread_create (__lambda0__gthread_func, block1_data_ref (_data1_),
block1_data_unref, FALSE, &_inner_error_);
As you can see, the second ccode produces one too many args for the
g_thread_create function, while for the first case the '_data1_' struct
is immediately freed as soon as the calling function is finished.
I don't really know how and if this can be fixed.
I thought this would be an easy option to hand over some parameters to a
thread function.
Are there other good options to put parameters to threads without
accessing class variables + mutex locking?
Regards
Jörn
Am Donnerstag, den 14.01.2010, 12:40 +0100 schrieb JM:

Hello all
Thanks Łukasz for your reply!
That explains the behavior. But then, shouldn't a thread also own the
thread function or will that lead to other issues?
Should the vapi binding be:
public static weak Thread create (owned ThreadFunc func, bool joinable)
throws ThreadError;
instdead of:
public static weak Thread create (ThreadFunc func, bool joinable) throws
ThreadError;
???
Then the closure handled by the thread will maybe not be freed too
early.
I really hope to clear all this because that looks like the only way to
pass some parameters to a threadfunction.
Regards,
Jörn
Am Donnerstag, den 14.01.2010, 11:06 +0100 schrieb Łukasz Pankowski:

JM <interflug1 gmx net> writes:

If I do the same thing with an Idle, the behavior is significantly
different, as the block data is not destroyed as soon as the run()
function is left. Why is that?
Well working example:
class HHH : Object {
public void run() {
string test = "test";
Idle.add(() => { print("in idle : %s \n", test); return false;});

if you look into glib-2.0.vapi Idle.add is declared as:
public static uint add (owned SourceFunc function, [CCode (pos = 0.1)] int priority =
Priority.DEFAULT_IDLE);
so the add() is declared to own the function past to it, so the closure data will be kept alive