Look for nanosleep function.
[platform/upstream/glib.git] / docs / reference / glib / tmpl / threads.sgml
index 68889f4..80f2c71 100644 (file)
@@ -4,7 +4,8 @@ Threads
 
 <!-- ##### SECTION Short_Description ##### -->
 
-thread abstraction; including mutexes, conditions and thread private data.
+thread abstraction; including threads, different mutexes, conditions
+and thread private data.
 
 <!-- ##### SECTION Long_Description ##### -->
 
@@ -15,33 +16,37 @@ communication between the involved threads via this shared memory, and
 it is bad, because strange things (so called Heisenbugs) might happen,
 when the program is not carefully designed. Especially bad is, that due
 to the concurrent nature of threads no assumptions on the order of
-execution of different threads can be done unless explictly forced by
+execution of different threads can be done unless explicitly forced by
 the programmer through synchronization primitives.
 </para>
 
 <para>
 The aim of the thread related functions in GLib is to provide a
-portable means for writing multithread safe software. There are
+portable means for writing multi-threaded software. There are
 primitives for mutexes to protect the access to portions of memory
-(#GMutex, #GStaticMutex, #G_LOCK_DEFINE and friends), there are
-primitives for condition variables to allow synchronization of threads
-(#GCond) and finally there are primitives for thread-private data,
-that every thread has a private instance of (#GPrivate,
-#GStaticPrivate).
-</para>
-
-<para>
-Currently there is only as much thread support included in GLib as is
-necessary to make GLib itself multithread safe. Version 1.4 of GLib
-will contain full thread support. For now the most portable way to
-create threads is to require the macro #G_THREADS_IMPL_POSIX to be
-defined and use POSIX threads then. This will work on almost all
-platforms (except most notably Solaris and DCE threads.).
+(#GMutex, #GStaticMutex, #G_LOCK_DEFINE, #GStaticRecMutex and
+#GStaticRWLock), there are primitives for condition variables to allow
+synchronization of threads (#GCond) and finally there are primitives
+for thread-private data, that every thread has a private instance of
+(#GPrivate, #GStaticPrivate). Last but definitely not least there are
+primitives to portably create and manage threads (#GThread).
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
+<variablelist>
+
+<varlistentry>
+<term>#GThreadPool</term>
+<listitem><para>Thread pools.</para></listitem>
+</varlistentry>
 
+<varlistentry>
+<term>#GAsyncQueue</term>
+<listitem><para>Send asynchronous messages between threads.</para></listitem>
+</varlistentry>
+
+</variablelist>
 </para>
 
 <!-- ##### MACRO G_THREADS_ENABLED ##### -->
@@ -50,8 +55,8 @@ platforms (except most notably Solaris and DCE threads.).
 This macro is defined, if GLib was compiled with thread support. This
 does not necessarily mean, that there is a thread implementation
 available, but the infrastructure is in place and once you provide a
-thread implementation to g_thread_init(), GLib will be multithread
-safe. It isn't and can't be, if #G_THREADS_ENABLED is not defined.
+thread implementation to g_thread_init(), GLib will be multi-thread
+safe. It isn't and cannot be, if #G_THREADS_ENABLED is not defined.
 </para>
 
 
@@ -67,7 +72,7 @@ This macro is defined, if POSIX style threads are used.
 <!-- ##### MACRO G_THREADS_IMPL_SOLARIS ##### -->
 
 <para>
-This macro is defined, if the SOLARIS thread system is used.
+This macro is defined, if the Solaris thread system is used.
 </para>
 
 
@@ -76,24 +81,25 @@ This macro is defined, if the SOLARIS thread system is used.
 
 <para>
 This macro is defined, if no thread implementation is used. You can
-however provide one to g_thread_init() to make GLib multithread safe.
+however provide one to g_thread_init() to make GLib multi-thread safe.
 </para>
 
 
 
 <!-- ##### MACRO G_THREAD_ERROR ##### -->
 <para>
-
+The error domain of the GLib thread subsystem.
 </para>
 
 
 
 <!-- ##### ENUM GThreadError ##### -->
 <para>
-
+Possible errors of thread related functions.
 </para>
 
-@G_THREAD_ERROR_AGAIN: 
+@G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource
+shortage. Try again later.
 
 <!-- ##### STRUCT GThreadFunctions ##### -->
 
@@ -151,7 +157,8 @@ really know, what you are doing.
 <note>
 <para>
 g_thread_init() must not be called directly or indirectly as a
-callback from GLib.
+call-back from GLib. Also no mutexes may be currently locked, while
+calling g_thread_init().
 </para>
 </note>
 
@@ -191,7 +198,7 @@ libraries.
 </note>
 
 @vtable: a function table of type #GThreadFunctions, that provides the
-entry points to the thread system to be used.
+entry points to the thread system to be used
 
 
 <!-- ##### FUNCTION g_thread_supported ##### -->
@@ -207,88 +214,239 @@ you can however use it as if it was a function.
 </para>
 </note>
 
-@Returns: TRUE, if the thread system is initialized.
+@Returns: TRUE, if the thread system is initialized
 
 
 <!-- ##### USER_FUNCTION GThreadFunc ##### -->
 <para>
-
+Specifies the type of the @func functions passed to
+g_thread_create() or g_thread_create_full().
 </para>
 
-@value: 
+@data: data passed to the thread
+@Returns: the return value of the thread, which will be returned by
+g_thread_join()
 
 
 <!-- ##### ENUM GThreadPriority ##### -->
 <para>
+Specifies the priority of a thread. 
+</para>
 
+<note>
+<para>
+It is not guaranteed, that threads with different priorities really
+behave accordingly. On some systems (e.g. Linux) only root can increase
+priorities. On other systems (e.g. Solaris) there doesn't seem to be
+different scheduling for different priorities. All in all try to avoid
+being dependent on priorities.
 </para>
+</note>
 
-@G_THREAD_PRIORITY_LOW: 
-@G_THREAD_PRIORITY_NORMAL: 
-@G_THREAD_PRIORITY_HIGH: 
-@G_THREAD_PRIORITY_URGENT: 
+@G_THREAD_PRIORITY_LOW: a priority lower than normal
+@G_THREAD_PRIORITY_NORMAL: the default priority
+@G_THREAD_PRIORITY_HIGH: a priority higher than normal
+@G_THREAD_PRIORITY_URGENT: the highest priority
 
 <!-- ##### STRUCT GThread ##### -->
 <para>
+The #GThread struct represents a running thread. It has three public
+read-only members, but the underlying struct is bigger, so you must
+not copy this struct.
+</para>
 
+<note>
+<para>
+Resources for a joinable thread are not fully released until
+g_thread_join() is called for that thread.
 </para>
+</note>
 
-@priority: 
-@bound: 
-@joinable: 
+@func: the function executing in that thread
+@data: the argument to the function
+@joinable: is this thread joinable?
+@priority: the priority of the thread
 
 <!-- ##### FUNCTION g_thread_create ##### -->
 <para>
+This function creates a new thread with the priority @priority.
+</para>
+
+<para>
+If @joinable is #TRUE, you can wait for this threads termination
+calling g_thread_wait(). Otherwise the thread will just disappear, when
+ready. 
+</para>
+
+<para>
+The new thread executes the function @func with the argument
+@data. If the thread was created successfully, it is returned.
+</para>
 
+<para>
+@error can be NULL to ignore errors, or non-NULL to report errors. The
+error is set, if and only if the function returns #NULL.
 </para>
 
-@thread_func: 
-@arg: 
-@stack_size: 
-@joinable: 
-@bound: 
-@priority: 
-@error: 
-@Returns: 
+@func: a function to execute in the new thread
+@data: an argument to supply to the new thread
+@joinable: should this thread be joinable?
+@error: return location for error.
+@Returns: the new #GThread on success
 
 
-<!-- ##### FUNCTION g_thread_self ##### -->
+<!-- ##### FUNCTION g_thread_create_full ##### -->
+<para>
+This function creates a new thread with the priority @priority. The
+stack gets the size @stack_size or the default value for the current
+platform, if @stack_size is 0.
+</para>
+
 <para>
+If @joinable is #TRUE, you can wait for this threads termination
+calling g_thread_wait(). Otherwise the thread will just disappear, when
+ready. If @bound is #TRUE, this thread will be scheduled in the system
+scope, otherwise the implementation is free to do scheduling in the
+process scope. The first variant is more expensive resource-wise, but
+generally faster. On some systems (e.g. Linux) all threads are bound.
+</para>
 
+<para>
+The new thread executes the function @func with the argument
+@data. If the thread was created successfully, it is returned.
 </para>
 
-@Returns: 
+<para>
+@error can be NULL to ignore errors, or non-NULL to report errors. The
+error is set, if and only if the function returns #NULL.
+</para>
+
+<note>
+<para>
+It is not guaranteed, that threads with different priorities really
+behave accordingly. On some systems (e.g. Linux) only root can increase
+priorities. On other systems (e.g. Solaris) there doesn't seem to be
+different scheduling for different priorities. All in all try to avoid
+being dependent on priorities. Use %G_THREAD_PRIORITY_NORMAL here as a
+default.
+</para>
+</note>
 
+<note>
+<para>
+Only use g_thread_create_full(), when you really can't use
+g_thread_create() instead. g_thread_create() does not take
+@stack_size, @bound and @priority as arguments, as they should only be
+used for cases, where it is inevitable. 
+</para>
+</note>
 
-<!-- ##### FUNCTION g_thread_join ##### -->
+@func: a function to execute in the new thread
+@data: an argument to supply to the new thread
+@stack_size: a stack size for the new thread
+@joinable: should this thread be joinable?
+@bound: should this thread be bound to a system thread?
+@priority: a priority for the thread
+@error: return location for error.
+@Returns: the new #GThread on success
+
+
+<!-- ##### FUNCTION g_thread_self ##### -->
 <para>
+This functions returns the #GThread corresponding to the calling thread.
+</para>
 
+@Returns: the current thread
+
+
+<!-- ##### FUNCTION g_thread_join ##### -->
+<para>
+Waits until @thread finishes, i.e. the function @func, as given
+to g_thread_create, returns or g_thread_exit() is called by
+@thread. All resources of @thread including the #GThread struct are
+released. @thread must have been created with @joinable=#TRUE in
+g_thread_create(). The value returned by @func or given to
+g_thread_exit() by @thread is returned by this function.
 </para>
 
-@thread: 
+@thread: a #GThread to be waited for
+@Returns: the return value of the thread
 
 
 <!-- ##### FUNCTION g_thread_set_priority ##### -->
 <para>
+Change the priority of @thread to @priority.
+</para>
+
+<note>
+<para>
+It is not guaranteed, that threads with different priorities really
+behave accordingly. On some systems (e.g. Linux) only root can increase
+priorities. On other systems (e.g. Solaris) there doesn't seem to be
+different scheduling for different priorities. All in all try to avoid
+being dependent on priorities.
+</para>
+</note>
+
+@thread: a #GThread
+@priority: a new priority for @thread
+
+
+<!-- ##### FUNCTION g_thread_yield ##### -->
+<para>
+Give way to other threads waiting to be scheduled. 
+</para>
 
+<para>
+This function is often used as a method to make busy wait less
+evil. But in most cases, you will encounter, there are better methods
+to do that. So in general you shouldn't use that function.
 </para>
 
-@thread: 
-@priority: 
 
 
-<!-- ##### MACRO g_thread_yield ##### -->
+<!-- ##### FUNCTION g_thread_exit ##### -->
 <para>
+Exit the current thread. If another thread is waiting for that thread
+using g_thread_join() and the current thread is joinable, the waiting
+thread will be woken up and getting @retval as the return value of
+g_thread_join(). If the current thread is not joinable, @retval is
+ignored. Calling
+</para>
 
+<para>
+<informalexample>
+<programlisting>
+g_thread_join (retval);
+</programlisting>
+</informalexample>
 </para>
 
+<para>
+is equivalent to calling 
+</para>
 
+<para>
+<informalexample>
+<programlisting>
+return retval;
+</programlisting>
+</informalexample>
+</para>
 
-<!-- ##### MACRO g_thread_exit ##### -->
 <para>
+in the function @func, as given to g_thread_create().
+</para>
 
+<note>
+<para>
+Never call g_thread_exit from within a thread of a #GThreadPool, as
+that will mess up the bookkeeping and lead to funny and unwanted
+results.
 </para>
+</note>
 
+@retval: the return value of this thread
 
 
 <!-- ##### STRUCT GMutex ##### -->
@@ -315,7 +473,7 @@ access. Take for example the following function:
 </para>
 
 <para>
-It is easy to see, that this won't work in a multithreaded
+It is easy to see, that this won't work in a multi-threaded
 application. There current_number must be protected against shared
 access. A first naive implementation would be:
 </para>
@@ -343,7 +501,7 @@ access. A first naive implementation would be:
 
 <para>
 This looks like it would work, but there is a race condition while
-constructing the mutex and this code can't work reliable. So please do
+constructing the mutex and this code cannot work reliable. So please do
 not use such constructs in your own programs. One working solution is:
 </para>
 
@@ -380,6 +538,12 @@ not use such constructs in your own programs. One working solution is:
 </para>
 
 <para>
+If you want to use a mutex, but your code should also work without
+calling g_thread_init() first, you can not use a #GMutex, as
+g_mutex_new() requires that. Use a #GStaticMutex instead.
+</para>
+
+<para>
 A #GMutex should only be accessed via the following functions.
 </para>
 
@@ -403,15 +567,15 @@ This function will abort, if g_thread_init() has not been called yet.
 </para>
 </note>
 
-@Returns: a new #GMutex.
+@Returns: a new #GMutex
 
 
 <!-- ##### FUNCTION g_mutex_lock ##### -->
 
 <para>
-Locks the #GMutex. If the #GMutex is already locked by another thread,
-the current thread will block until the #GMutex is unlocked by the
-other thread.
+Locks @mutex. If @mutex is already locked by another thread, the
+current thread will block until @mutex is unlocked by the other
+thread.
 </para>
 
 <para>
@@ -421,20 +585,20 @@ called and will do nothing then.
 
 <note>
 <para>
-#GMutex is not guaranteed to be recursive, i.e. a thread might block,
-if it already has locked the #GMutex. It will deadlock then, of
-course.
+#GMutex is not recursive, i.e. a thread will deadlock, if it already
+has locked @mutex while calling g_mutex_lock(). Use
+#GStaticRecMutex instead, if you need recursive mutexes.
 </para>
 </note>
 
-@mutex: a #GMutex.
+@mutex: a #GMutex
 
 
 <!-- ##### FUNCTION g_mutex_trylock ##### -->
 
 <para>
-Tries to lock the #GMutex. If the #GMutex is already locked by another
-thread, it immediately returns FALSE. Otherwise it locks the #GMutex
+Tries to lock @mutex. If @mutex is already locked by another
+thread, it immediately returns FALSE. Otherwise it locks @mutex
 and returns TRUE.
 </para>
 
@@ -443,29 +607,40 @@ This function can also be used, if g_thread_init() has not yet been
 called and will immediately return TRUE then.
 </para>
 
-@mutex: a #GMutex.
-@Returns: TRUE, if the #GMutex could be locked.
+<note>
+<para>
+#GMutex is not recursive, i.e. g_mutex_trylock() will return FALSE,
+if the current thread already has locked @mutex. Use
+#GStaticRecMutex instead, if you need recursive mutexes.
+</para>
+</note>
+
+@mutex: a #GMutex
+@Returns: TRUE, if @mutex could be locked
 
 
 <!-- ##### FUNCTION g_mutex_unlock ##### -->
 
 <para>
-Unlocks the #GMutex. If another thread is blocked in a g_mutex_lock()
-call, it will be woken and can lock the #GMutex itself. This function
-can also be used, if g_thread_init() has not yet been called and will
-do nothing then.
+Unlocks @mutex. If another thread is blocked in a g_mutex_lock() call
+for @mutex, it will be woken and can lock @mutex itself.
+</para>
+
+<para>
+This function can also be used, if g_thread_init() has not yet been
+called and will do nothing then.
 </para>
 
-@mutex: a #GMutex.
+@mutex: a #GMutex
 
 
 <!-- ##### FUNCTION g_mutex_free ##### -->
 
 <para>
-Destroys the #GMutex.
+Destroys @mutex.
 </para>
 
-@mutex: a #GMutex.
+@mutex: a #GMutex
 
 
 <!-- ##### STRUCT GStaticMutex ##### -->
@@ -497,13 +672,25 @@ safer version of our give_me_next_number() example:
 </para>
 
 <para>
+Sometimes you would like to dynamically create a mutex. If you don't
+want to require prior calling to g_thread_init(), because your code
+should also be usable in non-threaded programs, you are not able to
+use g_mutex_new() and thus #GMutex, as that requires a prior call to
+g_thread_init(). In theses cases you can also use a #GStaticMutex. It
+must be initialized with g_static_mutex_init() before using it and
+freed with with g_static_mutex_free() when not needed anymore to free
+up any allocated recourses.
+</para>
+
+<para>
 Even though #GStaticMutex is not opaque, it should only be used with
 the following functions, as it is defined differently on different
 platforms.
 </para>
 
-<para>All of the g_static_mutex_* functions can also be used, if
-g_thread_init() has not yet.
+<para>
+All of the g_static_mutex_* functions can also be used, if
+g_thread_init() has not yet been called.
 </para>
 
 <note>
@@ -518,46 +705,56 @@ functions.
 <!-- ##### MACRO G_STATIC_MUTEX_INIT ##### -->
 
 <para>
-Every #GStaticMutex must be initialized with this macro, before it can
-be used.
+A #GStaticMutex 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_mutex_init().
 </para>
 
 <para>
-<example>
-<title>Initializing a GStaticMutext</title>
+<informalexample>
 <programlisting>
 GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;
 </programlisting>
-</example>
+</informalexample>
+</para>
+
+
+
+<!-- ##### FUNCTION g_static_mutex_init ##### -->
+<para>
+Initializes @mutex. Alternatively you can initialize it with
+#G_STATIC_MUTEX_INIT.
 </para>
 
+@mutex: a #GStaticMutex to be initialized
 
 
 <!-- ##### FUNCTION g_static_mutex_lock ##### -->
 <para>
-works like g_mutex_lock(), but for a #GStaticMutex.
+Works like g_mutex_lock(), but for a #GStaticMutex.
 </para>
 
-@mutex: a #GStaticMutex.
+@mutex: a #GStaticMutex
 
 
 <!-- ##### FUNCTION g_static_mutex_trylock ##### -->
 
 <para>
-works like g_mutex_trylock(), but for a #GStaticMutex.
+Works like g_mutex_trylock(), but for a #GStaticMutex.
 </para>
 
-@mutex: a #GStaticMutex.
-@Returns: TRUE, if the #GStaticMutex could be locked.
+@mutex: a #GStaticMutex
+@Returns: TRUE, if the #GStaticMutex could be locked
 
 
 <!-- ##### FUNCTION g_static_mutex_unlock ##### -->
 
 <para>
-works like g_mutex_unlock(), but for a #GStaticMutex.
+Works like g_mutex_unlock(), but for a #GStaticMutex.
 </para>
 
-@mutex: a #GStaticMutex.
+@mutex: a #GStaticMutex
 
 
 <!-- ##### FUNCTION g_static_mutex_get_mutex ##### -->
@@ -565,11 +762,26 @@ works like g_mutex_unlock(), but for a #GStaticMutex.
 <para>
 For some operations (like g_cond_wait()) you must have a #GMutex
 instead of a #GStaticMutex. This function will return the
-corresponding #GMutex for every #GStaticMutex.
+corresponding #GMutex for @mutex.
 </para>
 
-@mutex: a #GStaticMutex.
-@Returns: the corresponding #GMutex.
+@mutex: a #GStaticMutex
+@Returns: the #GMutex corresponding to @mutex
+
+
+<!-- ##### FUNCTION g_static_mutex_free ##### -->
+<para>
+Releases all resources allocated to @mutex. 
+</para>
+
+<para>
+You don't have to call this functions for a #GStaticMutex with an
+unbounded lifetime, i.e. objects declared 'static', but if you have a
+#GStaticMutex as a member of a structure and the structure is freed,
+you should also free the #GStaticMutex.
+</para>
+
+@mutex: a #GStaticMutex to be freed
 
 
 <!-- ##### MACRO G_LOCK_DEFINE ##### -->
@@ -578,8 +790,8 @@ corresponding #GMutex for every #GStaticMutex.
 The G_LOCK_* macros provide a convenient interface to #GStaticMutex
 with the advantage that they will expand to nothing in programs
 compiled against a thread-disabled GLib, saving code and memory
-there. #G_LOCK_DEFINE defines a lock. It can occur, where variable
-definitions may occur in programs, i.e. in the first block of a
+there. #G_LOCK_DEFINE defines a lock. It can appear, where variable
+definitions may appear in programs, i.e. in the first block of a
 function or outside of functions. The @name parameter will be mangled
 to get the name of the #GStaticMutex. This means, that you can use
 names of existing variables as the parameter, e.g. the name of the
@@ -607,7 +819,7 @@ int give_me_next_number ()
 </example>
 </para>
 
-@name: the name of the lock.
+@name: the name of the lock
 
 
 <!-- ##### MACRO G_LOCK_DEFINE_STATIC ##### -->
@@ -616,7 +828,7 @@ int give_me_next_number ()
 This works like #G_LOCK_DEFINE, but it creates a static object.
 </para>
 
-@name: the name of the lock.
+@name: the name of the lock
 
 
 <!-- ##### MACRO G_LOCK_EXTERN ##### -->
@@ -625,40 +837,56 @@ This works like #G_LOCK_DEFINE, but it creates a static object.
 This declares a lock, that is defined with #G_LOCK_DEFINE in another module.
 </para>
 
-@name: the name of the lock.
+@name: the name of the lock
 
 
 <!-- ##### MACRO G_LOCK ##### -->
 
 <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>
 
-@name: the name of the lock.
+@name: the name of the lock
 
 
 <!-- ##### MACRO G_TRYLOCK ##### -->
 
 <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>
 
-@name: the name of the lock.
-@Returns: TRUE, if the lock could be locked.
+@name: the name of the lock
+@Returns: TRUE, if the lock could be locked
 
 
 <!-- ##### MACRO G_UNLOCK ##### -->
 
 <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>
 
-@name: the name of the lock.
+@name: the name of the lock
 
 
 <!-- ##### STRUCT GStaticRecMutex ##### -->
 <para>
+A #GStaticRecMutex works like a #GStaticMutex, but it can be locked
+multiple times by one thread. If you enter it n times, however, you
+have to unlock it n times again to let other threads lock it. An
+exception is the function g_static_rec_mutex_unlock_full(), that
+allows you to unlock a #GStaticRecMutex completely returning the depth,
+i.e. the number of times this mutex was locked. The depth can later be
+used to restore the state by calling g_static_rec_mutex_lock_full().
+</para>
+
+<para>
+Even though #GStaticRecMutex is not opaque, it should only be used with
+the following functions.
+</para>
 
+<para>
+All of the g_static_rec_mutex_* functions can also be used, if
+g_thread_init() has not been called.
 </para>
 
 @mutex: 
@@ -667,58 +895,197 @@ works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE.
 
 <!-- ##### MACRO G_STATIC_REC_MUTEX_INIT ##### -->
 <para>
+A #GStaticRecMutex 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_rec_mutex_init().
+</para>
+
+<para>
+<informalexample>
+<programlisting>
+GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;
+</programlisting>
+</informalexample>
+</para>
+
 
+
+<!-- ##### FUNCTION g_static_rec_mutex_init ##### -->
+<para>
+A #GStaticRecMutex must be initialized with this function, before it
+can be used. Alternatively you can initialize it with
+#G_STATIC_REC_MUTEX_INIT.
 </para>
 
+@mutex: a #GStaticRecMutex to be initialized
 
 
 <!-- ##### FUNCTION g_static_rec_mutex_lock ##### -->
 <para>
-
+Locks @mutex. If @mutex is already locked by another thread, the
+current thread will block until @mutex is unlocked by the other
+thread. If @mutex is already locked by the calling thread, this
+functions increases the depth of @mutex and returns immediately.
 </para>
 
-@mutex: 
+@mutex: a #GStaticRecMutex to lock
 
 
 <!-- ##### FUNCTION g_static_rec_mutex_trylock ##### -->
 <para>
-
+Tries to lock @mutex. If @mutex is already locked by another thread,
+it immediately returns #FALSE. Otherwise it locks @mutex and returns
+#TRUE. If @mutex is already locked by the calling thread, this
+functions increases the depth of @mutex and immediately  returns #TRUE.
 </para>
 
-@mutex: 
-@Returns: 
+@mutex: a #GStaticRecMutex to lock
+@Returns: TRUE, if @mutex could be locked
 
 
 <!-- ##### FUNCTION g_static_rec_mutex_unlock ##### -->
 <para>
-
+Unlocks @mutex. Another threads can, however, only lock @mutex when it
+has been unlocked as many times, as it had been locked before. If
+@mutex is completely unlocked and another thread is blocked in a
+g_static_rec_mutex_lock() call for @mutex, it will be woken and can
+lock @mutex itself.
 </para>
 
-@mutex: 
+@mutex: a #GStaticRecMutex to unlock
 
 
 <!-- ##### FUNCTION g_static_rec_mutex_lock_full ##### -->
 <para>
-
+Works like calling g_static_rec_mutex_lock() for @mutex n times.
 </para>
 
-@mutex: 
-@depth: 
+@mutex: a #GStaticRecMutex to lock
+@depth: number of times this mutex has to be unlocked to be completely unlocked
 
 
 <!-- ##### FUNCTION g_static_rec_mutex_unlock_full ##### -->
 <para>
+Completely unlocks @mutex. If another thread is blocked in a
+g_static_rec_mutex_lock() call for @mutex, it will be woken and can
+lock @mutex itself. This function returns the number of times, that
+@mutex has been locked by the current thread. To restore the state
+before the call to g_static_rec_mutex_unlock_full() you can call
+g_static_rec_mutex_lock_full() with the depth returned by this
+function.
+</para>
+
+@mutex: a #GStaticRecMutex to completely unlock
+@Returns: number of times @mutex has been locked by the current thread
+
 
+<!-- ##### FUNCTION g_static_rec_mutex_free ##### -->
+<para>
+Releases all resources allocated to a #GStaticRecMutex.
 </para>
 
-@mutex: 
-@Returns: 
+<para>
+You don't have to call this functions for a #GStaticRecMutex with an
+unbounded lifetime, i.e. objects declared 'static', but if you have a
+#GStaticRecMutex as a member of a structure and the structure is
+freed, you should also free the #GStaticRecMutex.
+</para>
+
+@mutex: a #GStaticRecMutex to be freed
 
 
 <!-- ##### STRUCT GStaticRWLock ##### -->
 <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 following
+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 (&amp;rwlock);
+
+    if (index < array->len)
+      retval = g_ptr_array_index (array, index);
+
+    g_static_rw_lock_reader_unlock (&amp;rwlock);
+
+    return retval;
+  }
 
+  void my_array_set (guint index, gpointer data)
+  {
+    g_static_rw_lock_writer_lock (&amp;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 (&amp;rwlock);
+  }
+</programlisting>
+</example>
+</para>
+
+<para>
+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) 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
+multi-thread safe now. 
+</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 #GStaticRWLock 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: 
 @read_cond: 
@@ -729,67 +1096,128 @@ works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE.
 
 <!-- ##### MACRO G_STATIC_RW_LOCK_INIT ##### -->
 <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>
 
 
 
+<!-- ##### FUNCTION g_static_rw_lock_init ##### -->
+<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>
+
+@lock: a #GStaticRWLock to be initialized
+
+
 <!-- ##### FUNCTION g_static_rw_lock_reader_lock ##### -->
 <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>
+#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: 
+@lock: a #GStaticRWLock to lock for reading
 
 
 <!-- ##### FUNCTION g_static_rw_lock_reader_trylock ##### -->
 <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>
 
-@lock: 
-@Returns: 
+@lock: a #GStaticRWLock to lock for reading
+@Returns: TRUE, if @lock could be locked for reading
 
 
 <!-- ##### FUNCTION g_static_rw_lock_reader_unlock ##### -->
 <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>
 
-@lock: 
+@lock: a #GStaticRWLock to unlock after reading
 
 
 <!-- ##### FUNCTION g_static_rw_lock_writer_lock ##### -->
 <para>
-
+Locks @lock for writing. If @lock is already locked for writing or
+reading by other threads, this function will block until @lock is
+completely 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>
 
-@lock: 
+@lock: a #GStaticRWLock to lock for writing
 
 
 <!-- ##### FUNCTION g_static_rw_lock_writer_trylock ##### -->
 <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>
 
-@lock: 
-@Returns: 
+@lock: a #GStaticRWLock to lock for writing
+@Returns: TRUE, if @lock could be locked for writing
 
 
 <!-- ##### FUNCTION g_static_rw_lock_writer_unlock ##### -->
 <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>
 
-@lock: 
+@lock: a #GStaticRWLock to unlock after writing
 
 
 <!-- ##### FUNCTION g_static_rw_lock_free ##### -->
 <para>
+Releases all resources allocated to @lock. 
+</para>
 
+<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: 
+@lock: a #GStaticRWLock to be freed
 
 
 <!-- ##### STRUCT GCond ##### -->
@@ -871,7 +1299,7 @@ Creates a new #GCond. This function will abort, if g_thread_init()
 has not been called yet.
 </para>
 
-@Returns: a new #GCond.
+@Returns: a new #GCond
 
 
 <!-- ##### FUNCTION g_cond_signal ##### -->
@@ -886,7 +1314,7 @@ This function can also be used, if g_thread_init() has
 not yet been called and will do nothing then.
 </para>
 
-@cond: a #GCond.
+@cond: a #GCond
 
 
 <!-- ##### FUNCTION g_cond_broadcast ##### -->
@@ -902,14 +1330,14 @@ This function can also be used, if g_thread_init() has
 not yet been called and will do nothing then.
 </para>
 
-@cond: a #GCond.
+@cond: a #GCond
 
 
 <!-- ##### FUNCTION g_cond_wait ##### -->
 
 <para>
-Waits until this thread is woken up on the #GCond. The #GMutex is
-unlocked before falling asleep and locked again before resuming.
+Waits until this thread is woken up on @cond. The @mutex is unlocked
+before falling asleep and locked again before resuming.
 </para>
 
 <para>
@@ -917,15 +1345,15 @@ This function can also be used, if g_thread_init() has not yet been
 called and will immediately return then.
 </para>
 
-@cond: a #GCond.
-@mutex: the #GMutex, that is currently locked.
+@cond: a #GCond
+@mutex: a #GMutex, that is currently locked
 
 
 <!-- ##### FUNCTION g_cond_timed_wait ##### -->
 
 <para>
-Waits until this thread is woken up on the #GCond, but not longer than
-until the time, that is specified by @abs_time. The #GMutex is
+Waits until this thread is woken up on @cond, but not longer than
+until the time, that is specified by @abs_time. The @mutex is
 unlocked before falling asleep and locked again before resuming.
 </para>
 
@@ -938,10 +1366,15 @@ This function can also be used, if g_thread_init() has not yet been
 called and will immediately return TRUE then.
 </para>
 
-@cond: a #GCond.
-@mutex: the #GMutex, that is currently locked.
-@abs_time: a #GTimeVal, determining the final time.
-@Returns: TRUE, if the thread is woken up in time.
+<para>
+To easily calculate @abs_time a combination of g_get_current_time()
+and g_time_val_add() can be used.
+</para>
+
+@cond: a #GCond
+@mutex: a #GMutex, that is currently locked
+@abs_time: a #GTimeVal, determining the final time
+@Returns: TRUE, if the thread is woken up in time
 
 
 <!-- ##### FUNCTION g_cond_free ##### -->
@@ -950,7 +1383,7 @@ called and will immediately return TRUE then.
 Destroys the #GCond.
 </para>
 
-@cond: a #GCond.
+@cond: a #GCond
 
 
 <!-- ##### STRUCT GPrivate ##### -->
@@ -1016,15 +1449,15 @@ destructor is called with this pointer as the argument.
 
 <note>
 <para>
-The @destructor is working quite differently from @notify in
+@destructor is working quite differently from @notify in
 g_static_private_set().
 </para>
 </note>
 
 <note>
 <para>
-A #GPrivate can not be destroyed. Reuse it instead, if you can to
-avoid shortage.
+A #GPrivate can not be freed. Reuse it instead, if you can to avoid
+shortage or use #GStaticPrivate.
 </para>
 </note>
 
@@ -1035,8 +1468,8 @@ This function will abort, if g_thread_init() has not been called yet.
 </note>
 
 @destructor: a function to handle the data keyed to #GPrivate, when a
-thread ends.
-@Returns: 
+thread ends
+@Returns: a new #GPrivate
 
 
 <!-- ##### FUNCTION g_private_get ##### -->
@@ -1052,8 +1485,8 @@ This function can also be used, if g_thread_init() has not yet been
 called and will return the value of @private_key casted to #gpointer then.
 </para>
 
-@private_key: a #GPrivate.
-@Returns: the corresponding pointer.
+@private_key: a #GPrivate
+@Returns: the corresponding pointer
 
 
 <!-- ##### FUNCTION g_private_set ##### -->
@@ -1067,10 +1500,8 @@ This function can also be used, if g_thread_init() has not yet been
 called and will set @private_key to @data casted to #GPrivate* then.
 </para>
 
-@private_key: a #GPrivate.
-@data: the new pointer.
-<!-- # Unused Parameters # -->
-@value: 
+@private_key: a #GPrivate
+@data: the new pointer
 
 
 <!-- ##### STRUCT GStaticPrivate ##### -->
@@ -1123,27 +1554,26 @@ GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;
 
 
 
-<!-- ##### FUNCTION g_static_private_get ##### -->
+<!-- ##### FUNCTION g_static_private_init ##### -->
 <para>
-Works like g_private_get() only for a #GStaticPrivate.
+Initializes @private_key. Alternatively you can initialize it with
+#G_STATIC_PRIVATE_INIT.
 </para>
 
-<para>
-This function also works, if g_thread_init() has not yet been called.
-</para>
-
-@private_key: a #GStaticPrivate.
-@Returns: the corresponding pointer.
+@private_key: a #GStaticPrivate to be initialized
 
 
-<!-- ##### FUNCTION g_static_private_get_for_thread ##### -->
+<!-- ##### FUNCTION g_static_private_get ##### -->
 <para>
+Works like g_private_get() only for a #GStaticPrivate.
+</para>
 
+<para>
+This function also works, if g_thread_init() has not yet been called.
 </para>
 
-@private_key: 
-@thread: 
-@Returns: 
+@private_key: a #GStaticPrivate
+@Returns: the corresponding pointer
 
 
 <!-- ##### FUNCTION g_static_private_set ##### -->
@@ -1162,25 +1592,29 @@ called g_thread_init().
 
 <note>
 <para>
-The @notify is working quite differently from @destructor in
+@notify is working quite differently from @destructor in
 g_private_new().
 </para>
 </note>
 
-@private_key: a #GStaticPrivate.
-@data: the new pointer.
+@private_key: a #GStaticPrivate
+@data: the new pointer
 @notify: a function to be called with the pointer, whenever the
-current thread ends or sets this pointer again.
+current thread ends or sets this pointer again
 
 
-<!-- ##### FUNCTION g_static_private_set_for_thread ##### -->
+<!-- ##### FUNCTION g_static_private_free ##### -->
 <para>
+Releases all resources allocated to @private_key. 
+</para>
 
+<para>
+You don't have to call this functions for a #GStaticPrivate with an
+unbounded lifetime, i.e. objects declared 'static', but if you have a
+#GStaticPrivate as a member of a structure and the structure is freed,
+you should also free the #GStaticPrivate.
 </para>
 
-@private_key: 
-@thread: 
-@data: 
-@notify: 
+@private_key: a #GStaticPrivate to be freed