I'm building a fairly simple C application using GTK, but have to perform some blocking IO which will trigger updates to the GUI. In order to do this, I start a new pthread
right before gtk_main()
as such:
/* global variables */
GMainContext *mainc;
/* local variables */
FILE *fifo;
pthread_t reader;
/* main() */
mainc = g_main_context_default();
pthread_create(&reader, NULL, watch_fifo, argv[argc-1]);
gtk_main();
When the pthread
reads some data, it updates the GUI like so:
g_main_context_invoke(mainc, set_icon, param);
Where set_icon
is
gboolean set_icon(gpointer data)
{
char *p = (char*)data;
gtk_status_icon_set_from_icon_name(icon, p);
return FALSE;
}
This all works most of the time, but every now and again I get this curious error message:
[xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. mktrayicon: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
I thought the whole point of using g_main_context_invoke
was to avoid issues with threads? Doing a bit of Googling, I came across gdk_threads_init
, gdk_threads_enter
and friends, but they all seem to be deprecated? I know the GTK documentation says that all GUI updaes should be performed on the main thread, but this does not combine all that well with blocking IO, and I'd prefer not to have to construct some complex communication mechanism between the threads.
And so, my question is, how should I correctly deal with this?
EDIT: The full code can be seen here
EDIT2: As an update based on @ptomato's answer, I've moved to GThread
s and using gdk_threads_add_idle()
as seen in this commit, but the problem is still present.