In GLib, is there an operation to tell it “acquire the lock if you don’t hold it already”? Can the same thread acquire a lock twice (making the second acquisition a no-op, or requiring it to be released twice) or test if it is already holding a particular lock?
Suppose I have the following functions in my code:
void func_a() {
//g_rw_lock_writer_lock(&shared_data->rw_lock);
mess_with_data(shared_data);
func_b();
//g_rw_lock_writer_unlock(&shared_data->rw_lock);
}
void func_b() {
//g_rw_lock_writer_lock(&shared_data->rw_lock);
mess_with_data_again(shared_data);
//g_rw_lock_writer_unlock(&shared_data->rw_lock);
}
Assume that:
shared_data
points to a shared data structure, and access needs to be synchronized between threadsshared_data->rw_lock
is the read/write lock to synchronize access- Both
func_a()
andfunc_b()
can be called from outside mess_with_data()
andmess_with_data_again()
are not thread-safe, thus the caller needs to hold a write lock on the data before calling them- They are not just single function calls but rows of statements, so copying the body of
func_b()
intofunc_a()
is not an option (code duplication, poor maintainability) - The callers of
func_a()
andfunc_b()
have no direct access to the lock, therefore locking needs to happen under the hood - Extracting the function body of
func_b()
(sans the locking/unlocking) into a separate helper function called by bothfunc_a()
andfunc_()
is not an option (they are spread out across multiple modules and there are layers of abstraction between the function calls—in fact,func_a()
does not directly callfunc_b()
by name but a pointer which happens to resolve tofunc_b()
).
How would I solve this?