GThreadPool seems unsuitable for scheduling and waiting for subtasks
Thread Pools are a simple way to queue up multiple tasks and not having to worry about thread creation and queue maintenance. It seems to have one limitation though, tasks that are pushed in the queue cannot create subtasks when g_thread_pool_free is being called to wait for all tasks to complete.
This is the same issue reported a while back in https://mail.gnome.org/archives/gtk-list/2009-September/msg00068.html (which had no replies as far as I can see).
Reproducer:
/* cc repro.c $(pkgconf --cflags --libs glib-2.0) */
#include <glib.h>
void func(gpointer data, gpointer user_data)
{
GThreadPool *pool = *(GThreadPool **)user_data;
guint val = GPOINTER_TO_UINT(data);
g_print("val = %d\n", val);
if (val == 1) {
g_thread_pool_push(pool, GUINT_TO_POINTER(2), NULL);
}
}
int main(void) {
GThreadPool *pool = NULL;
pool = g_thread_pool_new(func, &pool, g_get_num_processors(), FALSE, NULL);
g_thread_pool_push(pool, GUINT_TO_POINTER(1), NULL);
/* g_usleep(10000); */
g_thread_pool_free(pool, FALSE /* immediate */, TRUE /* wait_ */);
return 0;
}
Expected result:
val = 1
val = 2
Actual result:
val = 1
(process:4586): GLib-CRITICAL **: 17:31:15.544: g_thread_pool_push: assertion 'real->running' failed
Related issue: #71n