GLib.RWLock¶
record (struct)
The GRWLock struct is an opaque data structure to represent a
reader-writer lock. It is similar to a Mutex in that it allows
multiple threads to coordinate access to a shared resource.
The difference to a mutex is that a reader-writer lock discriminates
between read-only ('reader') and full ('writer') access. While only
one thread at a time is allowed write access (by holding the 'writer'
lock via RWLock.writer_lock), multiple threads can gain
simultaneous read-only access (by holding the 'reader' lock via
RWLock.reader_lock).
It is unspecified whether readers or writers have priority in acquiring the lock when a reader already holds the lock and a writer is queued to acquire it.
Here is an example for an array with access functions:
GRWLock lock;
GPtrArray *array;
gpointer
my_array_get (guint index)
{
gpointer retval = NULL;
if (!array)
return NULL;
g_rw_lock_reader_lock (&lock);
if (index < array->len)
retval = g_ptr_array_index (array, index);
g_rw_lock_reader_unlock (&lock);
return retval;
}
void
my_array_set (guint index, gpointer data)
{
g_rw_lock_writer_lock (&lock);
if (!array)
array = g_ptr_array_new ();
if (index >= array->len)
g_ptr_array_set_size (array, index+1);
g_ptr_array_index (array, index) = data;
g_rw_lock_writer_unlock (&lock);
}
This example shows an array which can be accessed by many readers (the my_array_get() function) simultaneously, whereas the writers (the my_array_set() function) will only be allowed one at a time and only if no readers currently access the array. This is because of the potentially dangerous resizing of the array. Using these functions is fully multi-thread safe now.
If a RWLock is allocated in static storage then it can be used
without initialisation. Otherwise, you should call
RWLock.init on it and RWLock.clear when done.
A GRWLock should only be accessed with the g_rw_lock_ functions.
Methods¶
clear¶
Frees the resources allocated to a lock with RWLock.init.
This function should not be used with a RWLock that has been
statically allocated.
Calling RWLock.clear when any thread holds the lock
leads to undefined behaviour.
init¶
Initializes a RWLock so that it can be used.
This function is useful to initialize a lock that has been allocated on the stack, or as part of a larger structure. It is not necessary to initialise a reader-writer lock that has been statically allocated.
To undo the effect of RWLock.init when a lock is no longer
needed, use RWLock.clear.
Calling RWLock.init on an already initialized RWLock leads
to undefined behaviour.
reader_lock¶
Obtain a read lock on rw_lock. If another thread currently holds
the write lock on rw_lock, the current thread will block until the
write lock was (held and) released. If another thread does not hold
the write lock, but is waiting for it, it is implementation defined
whether the reader or writer will block. Read locks can be taken
recursively.
Calling RWLock.reader_lock while the current thread already
owns a write lock leads to undefined behaviour. Read locks however
can be taken recursively, in which case you need to make sure to
call RWLock.reader_unlock the same amount of times.
It is implementation-defined how many read locks are allowed to be held on the same lock simultaneously. If the limit is hit, or if a deadlock is detected, a critical warning will be emitted.
reader_trylock¶
Tries to obtain a read lock on rw_lock and returns True if
the read lock was successfully obtained. Otherwise it
returns False.
reader_unlock¶
Release a read lock on rw_lock.
Calling RWLock.reader_unlock on a lock that is not held
by the current thread leads to undefined behaviour.
writer_lock¶
Obtain a write lock on rw_lock. If another thread currently holds
a read or write lock on rw_lock, the current thread will block
until all other threads have dropped their locks on rw_lock.
Calling RWLock.writer_lock while the current thread already
owns a read or write lock on rw_lock leads to undefined behaviour.
writer_trylock¶
Tries to obtain a write lock on rw_lock. If another thread
currently holds a read or write lock on rw_lock, it immediately
returns False.
Otherwise it locks rw_lock and returns True.
writer_unlock¶
Release a write lock on rw_lock.
Calling RWLock.writer_unlock on a lock that is not held
by the current thread leads to undefined behaviour.