Sign up

Questions about GTK sub thread gui operation and "worker thread"

Hi, I'm writing a GUI application recently, and as GTK-IS-NOT-THREAD-SAFE, so, I have some code as below:

class epcTags
{
    EPCType epc;
    ulong times;

    this ()
    {
        times = 0;
    }
}

__gshared epcTags[] epcTagsArray;

/* Callback for a D module which has a backgroud thread running.*/
void epcReadCB(in EPCType epc)
{
    epcTags tag = new epcTags();
    tag.epc = epc;
    tag.times = 1;

    foreach (t; epcTagsArray) {
        if (t.epc == epc) {
            t.times++;
            return;
        }
    }

    epcTagsArray ~= tag;
}

/* GTK gui thread */
int _trytimes = 0;
extern(C) nothrow static int threadIdleProcess(void* data) {
	//Don't let D exceptions get thrown from function
    try {
        if (_isRFIDReading) {
            _ui.rfidProgress.pulse();
            /* put epc data to ui list */
            _ui.listTagStore.clear();
            foreach (tag; epcTagsArray) {
                TreeIter iter = _ui.listTagStore.createIter();
                _ui.listTagStore.setValue(iter, TAGLIST_COL1, bytesToHexStr(tag.epc));
                _ui.listTagStore.setValue(iter, TAGLIST_COL2, tag.times);
                _ui.listTagStore.setValue(iter, TAGLIST_COL3, false);
            }
            return 1;
        }
        else {
            return 0;
        }
	} catch (Throwable t) {
		return 0;
    }
}


mainGTKAppUILogic()
{
  ..........
  gdk.Threads.threadsAddIdle(&threadIdleProcess, null);
  ..........
}

The code actually works, but for me, I found it very strange, the threadIdelPRocss is something not D. and data will be passed using void * data, which is not D as well.

I tried to use the D lang signal/solt in STD-library, but, it's not suitable for gtk main thread as well. which i want to do is emit or send some msg in a clean GUI-less D thread, when data got, it tells the main gtk gui to display that data. using socket api to do such thing is a way, but it's another kind of complex.

So, is there a more idiomatic and simple way of doing this?

PS: why GtkD is not a kind thing like PyGI using the introspection kind of binding instead of using static binding ? AND I found the gernerated GtkD is not that valueable for a reference, all description is just copied from gtk-c document, it's useless. So when I learning to use something, what I did is just reading PyGtk3 tutorial and then find out is there a equal in GtkD, it's painfull. But, anyway, GtkD is useable. Thanks for the greate project.

Re: Questions about GTK sub thread gui operation and "worker thread"

On 02-01-18 04:17, binghoo dang wrote:

The code actually works, but for me, I found it very strange, the threadIdelPRocss is something not D. and data will be passed using void * data, which is not D as well.

I tried to use the D lang signal/solt in STD-library, but, it's not suitable for gtk main thread as well. which i want to do is emit or send some msg in a clean GUI-less D thread, when data got, it tells the main gtk gui to display that data. using socket api to do such thing is a way, but it's another kind of complex.

So, is there a more idiomatic and simple way of doing this?

You could use glib.Idle in combination with std.concurrency:
https://gist.github.com/MikeWey/f16073ed3ce905067fcb62cc6bb1b9c0#file-demomultithread-d-L132

std.signals is not thread safe and std.concurrency would be the D way to
pass messages between threads.

PS: why GtkD is not a kind thing like PyGI using the introspection kind of binding instead of using static binding ? AND I found the gernerated GtkD is not that valueable for a reference, all description is just copied from gtk-c document, it's useless. So when I learning to use something, what I did is just reading PyGtk3 tutorial and then find out is there a equal in GtkD, it's painfull. But, anyway, GtkD is useable. Thanks for the greate project.

GtkD is generated using gobject introspection, doing this at runtime
like PyGi doesn't seen feasible to me for a strongly typed, compiled
language.

And indeed the documentation can use some work.

Re: Questions about GTK sub thread gui operation and "worker thread"

On Tue, 2 Jan 2018 12:56:53 +0100, Mike Wey wrote:

I tried to use the D lang signal/solt in STD-library, but, it's not suitable for gtk main thread as well. which i want to do is emit or send some msg in a clean GUI-less D thread, when data got, it tells the main gtk gui to display that data. using socket api to do such thing is a way, but it's another kind of complex.

So, is there a more idiomatic and simple way of doing this?

You could use glib.Idle in combination with std.concurrency:
https://gist.github.com/MikeWey/f16073ed3ce905067fcb62cc6bb1b9c0#file-demomultithread-d-L132

std.signals is not thread safe and std.concurrency would be the D way to
pass messages between threads.

thank you mike.
I know the code you mentioned above. but I think that we may have a way to and a D-style callback rather the C-style.

PS: why GtkD is not a kind thing like PyGI using the introspection kind of binding instead of using static binding ? AND I found the gernerated GtkD is not that valueable for a reference, all description is just copied from gtk-c document, it's useless. So when I learning to use something, what I did is just reading PyGtk3 tutorial and then find out is there a equal in GtkD, it's painfull. But, anyway, GtkD is useable. Thanks for the greate project.

GtkD is generated using gobject introspection, doing this at runtime
like PyGi doesn't seen feasible to me for a strongly typed, compiled
language.

And indeed the documentation can use some work.

I finally found that GtkD is based on gir-to-d.

For the document, we really need to improve it as abstracted from gtk c code comment is really just not that helpful. You know, all the description is talking about c pointers and function callback and saying like this "This text is also used to select the stock item if gtkbuttonsetusestock() is used. "

Re: Questions about GTK sub thread gui operation and "worker thread"

On 03-01-18 03:56, binghoo dang wrote:

thank you mike.
I know the code you mentioned above. but I think that we may have a way to and a D-style callback rather the C-style.

Unlike the demo the code liked uses a D delegate, i think this is the
best we can do for now for getting messages from other threads into the
GLib mainloop.