Detect whether currently running on main thread

My UI involves lots of threads, and often call gdk_threads_idle_add to apply updates to UI.
Some of the calls need the result to be returned back,
so I let the calling thread listen to the mutex to be written by the idle task.

Problem is, main loop will deadlock if I accidentally call such function from the main thread. The calling main thread is waiting for main loop inside the main loop! I would like to detect such occasions so I could debug these cases easily.
In short, is there a way to detect if current thread is the main thread?

Thanks in advance.

You may call g_thread_self() from either main or your GtkApplication::startup signal handler and store the returned id:

static GThread *main_thread_id;

is_main_thread (void)
  assert (main_thread_id != NULL);

  return g_thread_self () == main_thread_id;

main ()
  main_thread_id = g_thread_self ();

  /* ... */

Is there any way to do it without global variable? It makes me feel iffy…

You could check if the current thread is the owner of the global default main context.

If you are passing messages between a worker thread and the main thread, you should probably have a GMainContext handle for each. For the main thread, this will be NULL. There should be a 1:1 correspondence between GMainContext instances and threads: each thread should have exactly one GMainContext. Any operation you’re running should probably have a pointer to the GMainContext it’s meant to run in or return its results to.

As such, you can check which GMainContext a function is running in by calling g_main_context_is_owner().

There’s an example of this in gnome-software (more here).

If you haven’t already, you should read these guides:


No matter what you do, you’ll come down to this, either directly by your application or a level below because there is no concept of “main thread” at the operating system level in Linux.

Your other option is to check if gettid() == getpid(), but this is Linux only (and there is no syscall wrapper for gettid().

GNOME Builder sets a global to g_thread_self() at startup and asserts everywhere we expect to be on the main thread to catch threading issues early and often.

1 Like

Thank you! In my case, I guess I can check if current thread is owner of global main context.

I see, I simply prefer global variable-involving stuffs to be handled by the layer below. I had bitten by globals, a lot…

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.