G_idle_add from a worker thread

So I’m trying to use g_idle_add from a worker thread, and as soon as I do no more idle functions get called. At all. From any thread, including the one I just added. In my case I return FALSE from the function every time. And re-add it via g_idle_add as needed.

Context: v3.22.30 on windows. But I see the same behaviour on Linux. I currently can’t get a v3.24 build working on windows to check that.

All the calls to g_idle_add from the main GUI thread work fine. Up until I need to return data from a worker thread and then it all just stops. Is there something I need to do to allow g_idle_add to be called from a thread?

Actually after posting this I found this article and tried the suggested call. And guess what? It works as advertised. Even from my worker thread!

So yay I guess. This is the version that works for me:

g_main_context_invoke_full(NULL, G_PRIORITY_DEFAULT, (GSourceFunc)IdleWrapper, &idle, NULL);

To the best of my knowledge, that is equivalent to:

g_idle_add (IdleWrapper, &idle);

except when used in the main thread. It is documented that g_main_context_invoke will use an idle source in any case where it cannot call the function directly.

The linked article (canonical location) is warning against using g_idle_add and friends when you don’t want to use the default context. You are passing NULL as the context, which has the same result.

Well in practice it’s quite different. Which may just be bug(s) manifesting. So temporarily I’m not blocked, so care a lot less than this morning.

The context of what I’m trying to do is send events up to the GUI thread from workers. The event consists of a message int and a few parameters. I store them in a queue and then trigger an idle function to pass them off to various views in the GUI (which aren’t quite widgets but similar in concept). I was using client events in GTK2 but they went away.

Actually g_main_context_invoke_full is not working. It sometimes runs the callback in the same thread as the calling code. While means that GUI methods get called from a worker thread when instead the IdleWrapper callback should only ever be called on the main thread. I wish g_idle_add was just thread aware. It would make like so much easier.

g_idle_add does exactly what you want; it always adds the idle source to the GMainContext for the main thread (g_main_context_default()). If this isn’t working, there is a bug in your code.