Class RWLock
- All Implemented Interfaces:
Proxy
GMutex 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 g_rw_lock_writer_lock()), multiple threads can gain simultaneous read-only access (by holding the 'reader' lock via g_rw_lock_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 GRWLock is allocated in static storage then it can be used
without initialisation. Otherwise, you should call
g_rw_lock_init() on it and g_rw_lock_clear() when done.
A GRWLock should only be accessed with the g_rw_lock_ functions.
- Since:
- 2.32
-
Constructor Summary
ConstructorsConstructorDescriptionRWLock()Allocate a new RWLock.Allocate a new RWLock.RWLock(MemorySegment address) Create a RWLock proxy instance for the provided memory address.RWLock(MemorySegment p, int[] i) Allocate a new RWLock with the fields set to the provided values.RWLock(MemorySegment p, int[] i, Arena arena) Allocate a new RWLock with the fields set to the provided values. -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()Frees the resources allocated to a lock with g_rw_lock_init().static MemoryLayoutThe memory layout of the native struct.voidinit()Initializes aGRWLockso that it can be used.voidObtain a read lock onrwLock.If another thread currently holds the write lock onrwLock,the current thread will block until the write lock was (held and) released.booleanTries to obtain a read lock on this RWLock and returnstrueif the read lock was successfully obtained.voidRelease a read lock onrwLock.@org.jspecify.annotations.Nullable int @Nullable []readI()Read the value of the fieldi.readP()Read the value of the fieldp.voidWrite a value in the fieldi.voidWrite a value in the fieldp.voidObtain a write lock onrwLock.If another thread currently holds a read or write lock onrwLock,the current thread will block until all other threads have dropped their locks onrwLock.booleanTries to obtain a write lock onrwLock.If another thread currently holds a read or write lock onrwLock,it immediately returnsfalse.voidRelease a write lock onrwLock.Methods inherited from class org.javagi.base.ProxyInstance
equals, handle, hashCode
-
Constructor Details
-
RWLock
Create a RWLock proxy instance for the provided memory address.- Parameters:
address- the memory address of the native object
-
RWLock
Allocate a new RWLock.- Parameters:
arena- to control the memory allocation scope
-
RWLock
public RWLock()Allocate a new RWLock. The memory is allocated withArena.ofAuto(). -
RWLock
Allocate a new RWLock with the fields set to the provided values.- Parameters:
p- value for the fieldpi- value for the fieldiarena- to control the memory allocation scope
-
RWLock
Allocate a new RWLock with the fields set to the provided values. The memory is allocated withArena.ofAuto().- Parameters:
p- value for the fieldpi- value for the fieldi
-
-
Method Details
-
getMemoryLayout
The memory layout of the native struct.- Returns:
- the memory layout
-
readP
-
writeP
Write a value in the fieldp.- Parameters:
p- The new value for the fieldp
-
readI
public @org.jspecify.annotations.Nullable int @Nullable [] readI()Read the value of the fieldi.- Returns:
- The value of the field
i
-
writeI
Write a value in the fieldi.- Parameters:
i- The new value for the fieldi
-
clear
public void clear()Frees the resources allocated to a lock with g_rw_lock_init().This function should not be used with a
GRWLockthat has been statically allocated.Calling g_rw_lock_clear() when any thread holds the lock leads to undefined behaviour.
- Since:
- 2.32
-
init
public void init()Initializes aGRWLockso 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.
typedef struct { GRWLock l; ... } Blob; Blob *b; b = g_new (Blob, 1); g_rw_lock_init (&b->l);To undo the effect of g_rw_lock_init() when a lock is no longer needed, use g_rw_lock_clear().
Calling g_rw_lock_init() on an already initialized
GRWLockleads to undefined behaviour.- Since:
- 2.32
-
readerLock
public void readerLock()Obtain a read lock onrwLock.If another thread currently holds the write lock onrwLock,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 g_rw_lock_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 g_rw_lock_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.
- Since:
- 2.32
-
readerTrylock
public boolean readerTrylock()Tries to obtain a read lock on this RWLock and returnstrueif the read lock was successfully obtained. Otherwise it returnsfalse.- Returns:
trueif this RWLock could be locked- Since:
- 2.32
-
readerUnlock
public void readerUnlock()Release a read lock onrwLock.Calling g_rw_lock_reader_unlock() on a lock that is not held by the current thread leads to undefined behaviour.
- Since:
- 2.32
-
writerLock
public void writerLock()Obtain a write lock onrwLock.If another thread currently holds a read or write lock onrwLock,the current thread will block until all other threads have dropped their locks onrwLock.Calling g_rw_lock_writer_lock() while the current thread already owns a read or write lock on this RWLock leads to undefined behaviour.
- Since:
- 2.32
-
writerTrylock
public boolean writerTrylock()Tries to obtain a write lock onrwLock.If another thread currently holds a read or write lock onrwLock,it immediately returnsfalse. Otherwise it locks this RWLock and returnstrue.- Returns:
trueif this RWLock could be locked- Since:
- 2.32
-
writerUnlock
public void writerUnlock()Release a write lock onrwLock.Calling g_rw_lock_writer_unlock() on a lock that is not held by the current thread leads to undefined behaviour.
- Since:
- 2.32
-