mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
C2001-03-07 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
C2001-03-07 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * glib/tmpl/threads.sgml: Completed. VS: ----------------------------------------------------------------------
This commit is contained in:
parent
665f0a4f50
commit
7208b0f183
@ -1,3 +1,7 @@
|
|||||||
|
2001-03-07 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
|
* glib/tmpl/threads.sgml: Completed.
|
||||||
|
|
||||||
Wed Mar 7 09:33:27 2001 Tim Janik <timj@gtk.org>
|
Wed Mar 7 09:33:27 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* gobject/Makefile.am: shuffled rules to avoid excessive
|
* gobject/Makefile.am: shuffled rules to avoid excessive
|
||||||
|
@ -654,7 +654,7 @@ Initializes @mutex. Alternatively you can initialize it with
|
|||||||
|
|
||||||
<!-- ##### FUNCTION g_static_mutex_lock ##### -->
|
<!-- ##### FUNCTION g_static_mutex_lock ##### -->
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_lock(), but for a #GStaticMutex.
|
Works like g_mutex_lock(), but for a #GStaticMutex.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@mutex: a #GStaticMutex
|
@mutex: a #GStaticMutex
|
||||||
@ -663,7 +663,7 @@ works like g_mutex_lock(), but for a #GStaticMutex.
|
|||||||
<!-- ##### FUNCTION g_static_mutex_trylock ##### -->
|
<!-- ##### FUNCTION g_static_mutex_trylock ##### -->
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_trylock(), but for a #GStaticMutex.
|
Works like g_mutex_trylock(), but for a #GStaticMutex.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@mutex: a #GStaticMutex
|
@mutex: a #GStaticMutex
|
||||||
@ -673,7 +673,7 @@ works like g_mutex_trylock(), but for a #GStaticMutex.
|
|||||||
<!-- ##### FUNCTION g_static_mutex_unlock ##### -->
|
<!-- ##### FUNCTION g_static_mutex_unlock ##### -->
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_unlock(), but for a #GStaticMutex.
|
Works like g_mutex_unlock(), but for a #GStaticMutex.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@mutex: a #GStaticMutex
|
@mutex: a #GStaticMutex
|
||||||
@ -765,7 +765,7 @@ This declares a lock, that is defined with #G_LOCK_DEFINE in another module.
|
|||||||
<!-- ##### MACRO G_LOCK ##### -->
|
<!-- ##### MACRO G_LOCK ##### -->
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE.
|
Works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@name: the name of the lock
|
@name: the name of the lock
|
||||||
@ -774,7 +774,7 @@ works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE.
|
|||||||
<!-- ##### MACRO G_TRYLOCK ##### -->
|
<!-- ##### MACRO G_TRYLOCK ##### -->
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE.
|
Works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@name: the name of the lock
|
@name: the name of the lock
|
||||||
@ -784,7 +784,7 @@ works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE.
|
|||||||
<!-- ##### MACRO G_UNLOCK ##### -->
|
<!-- ##### MACRO G_UNLOCK ##### -->
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE.
|
Works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@name: the name of the lock
|
@name: the name of the lock
|
||||||
@ -919,8 +919,95 @@ freed, you should also free the #GStaticRecMutex.
|
|||||||
|
|
||||||
<!-- ##### STRUCT GStaticRWLock ##### -->
|
<!-- ##### STRUCT GStaticRWLock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
The #GStaticRWLock struct represents a read-write lock. A read-write
|
||||||
|
lock can be used for protecting data, that some portions of code only
|
||||||
|
read from, while others also write. In such situations it is
|
||||||
|
desirable, that several readers can read at once, whereas of course
|
||||||
|
only one writer may write at a time. Take a look at the followin
|
||||||
|
example:
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>An array with access functions</title>
|
||||||
|
<programlisting>
|
||||||
|
GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
|
||||||
|
|
||||||
|
GPtrArray *array;
|
||||||
|
|
||||||
|
gpointer my_array_get (guint index)
|
||||||
|
{
|
||||||
|
gpointer retval = NULL;
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g_static_rw_lock_reader_lock (&rwlock);
|
||||||
|
|
||||||
|
if (index < array->len)
|
||||||
|
retval = g_ptr_array_index (array, index);
|
||||||
|
|
||||||
|
g_static_rw_lock_reader_unlock (&rwlock);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_array_set (guint index, gpointer data)
|
||||||
|
{
|
||||||
|
g_static_rw_lock_writer_lock (&rwlock);
|
||||||
|
|
||||||
|
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_static_rw_lock_writer_unlock (&rwlock);
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This example shows an array, which can be accessed by many readers
|
||||||
|
(the my_array_get function) simultaniously, whereas the writers (the
|
||||||
|
my_array_set function) only will be allowed once a time and only if no
|
||||||
|
readers currently access the array. This is because of the potentially
|
||||||
|
dangerous resizing of the array. Using that functions is fully
|
||||||
|
multithread safe now.
|
||||||
|
</para>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
Most of the time the writers should have precedence of readers. That
|
||||||
|
means for this implementation, that as soon as a writer wants to lock
|
||||||
|
the data, no other reader is allowed to lock the data, whereas of
|
||||||
|
course the readers, that already have locked the data are allowed to
|
||||||
|
finish their operation. As soon as the last reader unlocks the data,
|
||||||
|
the writer will lock it.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Even though #GStaticRWLoc is not opaque, it should only be used with
|
||||||
|
the following functions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
All of the g_static_rw_lock_* functions can also be used, if
|
||||||
|
g_thread_init() has not been called.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
A read-write lock has a higher overhead as a mutex. For example both
|
||||||
|
g_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock()
|
||||||
|
has to lock and unlock a #GStaticMutex, so it takes at least twice the
|
||||||
|
time to lock and unlock a #GStaticRWLock than to lock and unlock a
|
||||||
|
#GStaticMutex. So only data structures, that are accessed by multiple
|
||||||
|
readers, which keep the lock for a considerable time justify a
|
||||||
|
#GStaticRWLock. The above example most probably would fare better with
|
||||||
|
a #GStaticMutex.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
@mutex:
|
@mutex:
|
||||||
@read_cond:
|
@read_cond:
|
||||||
@ -931,75 +1018,128 @@ freed, you should also free the #GStaticRecMutex.
|
|||||||
|
|
||||||
<!-- ##### MACRO G_STATIC_RW_LOCK_INIT ##### -->
|
<!-- ##### MACRO G_STATIC_RW_LOCK_INIT ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
A #GStaticRWLock must be initialized with this macro, before it can
|
||||||
|
be used. This macro can used be to initialize a variable, but it
|
||||||
|
cannot be assigned to a variable. In that case you have to use
|
||||||
|
g_static_rw_lock_init().
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<informalexample>
|
||||||
|
<programlisting>
|
||||||
|
GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;
|
||||||
|
</programlisting>
|
||||||
|
</informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_init ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_init ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
A #GStaticRWLock must be initialized with this function, before it can
|
||||||
|
be used. Alternatively you can initialize it with
|
||||||
|
#G_STATIC_RW_LOCK_INIT.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to be initialized
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_reader_lock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_reader_lock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Locks @lock for reading. There may be unlimited concurrent locks for
|
||||||
|
reading of a #GStaticRWLock at the same time. If @lock is already
|
||||||
|
locked for writing by another thread or if another thread is already
|
||||||
|
waiting to lock @lock for writing, this function will block until
|
||||||
|
@lock is unlocked by the other writing thread and no other writing
|
||||||
|
threads want to lock @lock. This lock has to be unlocked by
|
||||||
|
g_static_rw_lock_reader_unlock().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
<para>
|
||||||
|
#GStaticRWLock in general is not recursive, but as there may be
|
||||||
|
unlimited concurrent locks for reading, it effectively is for
|
||||||
|
recursive for reading, but for reading only. Locking for writing after
|
||||||
|
locking for reading will deadlock, the same holds true for the
|
||||||
|
opposite order.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@lock: a #GStaticRWLock to lock for reading
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_reader_trylock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_reader_trylock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Tries to lock @lock for reading. If @lock is already locked for
|
||||||
|
writing by another thread or if another thread is already waiting to
|
||||||
|
lock @lock for writing, it immediately returns #FALSE. Otherwise it
|
||||||
|
locks @lock for reading and returns TRUE. This lock has to be unlocked
|
||||||
|
by g_static_rw_lock_reader_unlock().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to lock for reading
|
||||||
@Returns:
|
@Returns: TRUE, if @lock could be locked for reading
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_reader_unlock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_reader_unlock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Unlocks @lock. If a thread waits to lock @lock for writing and all
|
||||||
|
locks for reading have been unlocked, the waiting thread is woken up
|
||||||
|
and can lock @lock for writing.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to unlock after reading
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_writer_lock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_writer_lock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Locks @lock for writing. If @lock is already locked for writing or
|
||||||
|
reading by other threads, this function will block until @lock is
|
||||||
|
completly unlocked and then lock @lock for writing. While this
|
||||||
|
functions waits to lock @lock, no other thread can lock @lock for
|
||||||
|
reading. When @lock is locked for writing, no other thread can lock
|
||||||
|
@lock (neither for reading nor writing). This lock has to be unlocked
|
||||||
|
by g_static_rw_lock_writer_unlock().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to lock for writing
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_writer_trylock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_writer_trylock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Tries to lock @lock for writing. If @lock is already locked (for
|
||||||
|
either reading or writing) by another thread, it immediately returns
|
||||||
|
#FALSE. Otherwise it locks @lock for writing and returns TRUE. This
|
||||||
|
lock has to be unlocked by g_static_rw_lock_writer_unlock().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to lock for writing
|
||||||
@Returns:
|
@Returns: TRUE, if @lock could be locked for writing
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_writer_unlock ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_writer_unlock ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Unlocks @lock. If a thread waits to lock @lock for writing and all
|
||||||
|
locks for reading have been unlocked, the waiting thread is woken up
|
||||||
|
and can lock @lock for writing. If no thread waits to lock @lock for
|
||||||
|
writing and threads wait to lock @lock for reading, the waiting
|
||||||
|
threads are woken up and can lock @lock for reading.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
@lock: a #GStaticRWLock to unlock after writing
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_static_rw_lock_free ##### -->
|
<!-- ##### FUNCTION g_static_rw_lock_free ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Releases all resources allocated to @lock.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@lock:
|
<para>
|
||||||
|
You don't have to call this functions for a #GStaticRWLock with an
|
||||||
|
unbounded lifetime, i.e. objects declared 'static', but if you have a
|
||||||
|
#GStaticRWLock as a member of a structure and the structure is freed,
|
||||||
|
you should also free the #GStaticRWLock.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@lock: a #GStaticRWLock to be freed
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### STRUCT GCond ##### -->
|
<!-- ##### STRUCT GCond ##### -->
|
||||||
|
Loading…
Reference in New Issue
Block a user