1

I use GLib/GObject and am facing the following problem:

I have a class my_class that will have several object instances in multiple threads during runtime, where each object will exist within a single thread (so there is a 1:1 relation between the thread and the object).

However, the object will access a shared resource and I need locking to protect access to that resource. Now, I need a global mutex (a GMutex in GLib world) instance, that is available to all threads/objects to lock onto.

My current approach is to create that mutex before the threads are spawned, and pass that global mutex along in the constructor. But I don't like that approach. The mutex is not of any concern of the calling code before creating the threads - it is only required for functionality by the my_class and should as such then only be part of the my_class for a clean OO design.

But how to create a single mutex from within my_class? I could create a static GMutex *global_mutex and have it as global variable, shared across all threads. But when/how to call g_mutex_new()? I'd like to have it in the constructor of my_class, but the code needs only to be run once. To achieve that, I need locking in the first place, and I face an Chicken-Egg problem.

Dynalon
  • 6,577
  • 10
  • 54
  • 84
  • Why can the mutex not be constructed as a member of the 'resource' class? – Martin James Oct 23 '13 at 09:29
  • @MartinJames because if the resource class creates the instance, there will be n different mutex instances created by n threads if you have the mutex private to the resource class. That way, every thread will only locks onto its own mutex, which is useless - in that case you don't need locking at all. If the mutex is a shared, global variable, you will create n instances of a mutex, and the global variable will randomly hold one of that. This will lead to race conditions, because threads will possible lock on a mutex instance that will get overwritten by other threads. – Dynalon Oct 23 '13 at 09:33
  • There is more than one resource class instance? – Martin James Oct 23 '13 at 09:42
  • There is only once resource for **all threads**. That why you need locking. Only one thread is allowed to access the shared resource at a time. – Dynalon Oct 23 '13 at 09:44
  • A sorry, you meant the _resource class_. Well, there is no resource class. The resource is actually a function call to a non-thread safe function, and it is not a Gobject object. – Dynalon Oct 23 '13 at 09:45

1 Answers1

2

What you want is a GStaticMutex. Declare it as a static local variable in the thread function, and initialize it with G_STATIC_MUTEX_INIT:

static GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;

This declares, defines and initializes the mutex, so it can be used directly.

See the example in the linked reference.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • How does that by any way solve the problem? Even if there is such a macro, I would still have n different mutexes in n different threads when called from within the thread. I need a single mutex shared by n threads. – Dynalon Oct 23 '13 at 08:26
  • @Dyna Then declare it as a global variable? Or if you want it only to be used within one source file, as a `static` global variable? – Some programmer dude Oct 23 '13 at 08:30
  • Pilebord: Did you read my posting? I say there that I can make GMutex a global variable. But how to instantiate it then? If I call `g_mutex_new()` in every thread, I still create n instances of the mutex - the only difference is that my global variable will point to a randomly instantiated one. This introducess hell-of-a-lot possible race conditions for the threads, as other threads might be using a mutex that gets overwritten later by another thread. – Dynalon Oct 23 '13 at 08:33
  • @Dyna That is what these macros are for! So you don't have to call any functions to create or initialize the structure. – Some programmer dude Oct 23 '13 at 08:36
  • @Dyna What you probably want is a `GStaticMutex`, I've updated my answer with that information, and with links to the documentation. – Some programmer dude Oct 23 '13 at 08:43
  • It does not say in the docs that `G_STATIC_MUTEX_INIT` is an implicit barrier nor does it seem to be thread-safe. It is just a convinience macro to use if glib is not compiled with thread support. I don't think it does what I need, but will have to look at the glib sources to be sure. – Dynalon Oct 23 '13 at 08:52
  • Just checked the source: https://git.gnome.org/browse/glib/tree/glib/deprecated/gthread.h?h=glib-2-32#n127 - Static mutexes or the macro do not have anything todo with thread synchronization at all and are not a solution to the problem – Dynalon Oct 23 '13 at 08:58
  • @Dyna It's a mutex, and can be used just as a `GMutex` but be allocated and initialized by the compiler instead of having to be dynamically created and initialized. What else do you want? – Some programmer dude Oct 23 '13 at 09:03
  • Just implemented it using GStaticMutex and it seems it does exactly what I wanted. The key factor is that is created at compile time and shared within the *compile unit* – Dynalon Oct 23 '13 at 09:57