Look for nanosleep function.
[platform/upstream/glib.git] / docs / reference / glib / tmpl / threads.sgml
index 2e23b2b..80f2c71 100644 (file)
@@ -22,7 +22,7 @@ the programmer through synchronization primitives.
 
 <para>
 The aim of the thread related functions in GLib is to provide a
-portable means for writing multithreaded 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, #GStaticRecMutex and
 #GStaticRWLock), there are primitives for condition variables to allow
@@ -55,7 +55,7 @@ primitives to portably create and manage threads (#GThread).
 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
+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>
 
@@ -81,7 +81,7 @@ 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>
 
 
@@ -157,7 +157,7 @@ really know, what you are doing.
 <note>
 <para>
 g_thread_init() must not be called directly or indirectly as a
-callback from GLib. Also no mutexes may be currently locked, while
+call-back from GLib. Also no mutexes may be currently locked, while
 calling g_thread_init().
 </para>
 </note>
@@ -219,11 +219,13 @@ you can however use it as if it was a function.
 
 <!-- ##### USER_FUNCTION GThreadFunc ##### -->
 <para>
-Specifies the type of the @thread_func functions passed to
-g_thread_create().
+Specifies the type of the @func functions passed to
+g_thread_create() or g_thread_create_full().
 </para>
 
-@value: data supplied to the thread
+@data: data passed to the thread
+@Returns: the return value of the thread, which will be returned by
+g_thread_join()
 
 
 <!-- ##### ENUM GThreadPriority ##### -->
@@ -248,9 +250,9 @@ being dependent on priorities.
 
 <!-- ##### STRUCT GThread ##### -->
 <para>
-The #Gthread struct represents a running thread. It has three public
-members, but the underlying struct is bigger, so you must not copy
-this struct. You also must not write that information.
+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>
@@ -260,12 +262,41 @@ g_thread_join() is called for that thread.
 </para>
 </note>
 
+@func: the function executing in that thread
+@data: the argument to the function
 @joinable: is this thread joinable?
-@bound: is this thread bound to a system thread?
 @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>
+
+@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_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.
@@ -281,8 +312,8 @@ generally faster. On some systems (e.g. Linux) all threads are bound.
 </para>
 
 <para>
-The new thread executes the function @thread_func with the argument
-@arg. If the thread was created successfully, it is returned.
+The new thread executes the function @func with the argument
+@data. If the thread was created successfully, it is returned.
 </para>
 
 <para>
@@ -301,8 +332,17 @@ default.
 </para>
 </note>
 
-@thread_func: a function to execute in the new thread
-@arg: an argument to supply to the new thread
+<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>
+
+@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?
@@ -321,14 +361,16 @@ This functions returns the #GThread corresponding to the calling thread.
 
 <!-- ##### FUNCTION g_thread_join ##### -->
 <para>
-Waits until @thread finishes, i.e. the function @thread_func, as given
+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().
+g_thread_create(). The value returned by @func or given to
+g_thread_exit() by @thread is returned by this function.
 </para>
 
 @thread: a #GThread to be waited for
+@Returns: the return value of the thread
 
 
 <!-- ##### FUNCTION g_thread_set_priority ##### -->
@@ -366,7 +408,34 @@ to do that. So in general you shouldn't use that function.
 <!-- ##### FUNCTION g_thread_exit ##### -->
 <para>
 Exit the current thread. If another thread is waiting for that thread
-using g_thread_join(), that thread will be woken up. 
+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>
+
+<para>
+in the function @func, as given to g_thread_create().
 </para>
 
 <note>
@@ -377,6 +446,7 @@ results.
 </para>
 </note>
 
+@retval: the return value of this thread
 
 
 <!-- ##### STRUCT GMutex ##### -->
@@ -403,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>
@@ -516,7 +586,7 @@ called and will do nothing then.
 <note>
 <para>
 #GMutex is not recursive, i.e. a thread will deadlock, if it already
-has locked the #GMutex while calling g_mutex_lock(). Use
+has locked @mutex while calling g_mutex_lock(). Use
 #GStaticRecMutex instead, if you need recursive mutexes.
 </para>
 </note>
@@ -537,6 +607,14 @@ This function can also be used, if g_thread_init() has not yet been
 called and will immediately return TRUE then.
 </para>
 
+<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
 
@@ -654,7 +732,7 @@ Initializes @mutex. Alternatively you can initialize it with
 
 <!-- ##### 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
@@ -663,7 +741,7 @@ works like g_mutex_lock(), but for 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
@@ -673,7 +751,7 @@ works like g_mutex_trylock(), but for a #GStaticMutex.
 <!-- ##### 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
@@ -765,7 +843,7 @@ This declares a lock, that is defined with #G_LOCK_DEFINE in another module.
 <!-- ##### 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
@@ -774,7 +852,7 @@ works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE.
 <!-- ##### 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
@@ -784,7 +862,7 @@ works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE.
 <!-- ##### 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
@@ -919,9 +997,96 @@ freed, you should also free the #GStaticRecMutex.
 
 <!-- ##### 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: 
 @write_cond: 
@@ -931,75 +1096,128 @@ freed, you should also free the #GStaticRecMutex.
 
 <!-- ##### 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: 
+@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 ##### -->
@@ -1148,6 +1366,11 @@ This function can also be used, if g_thread_init() has not yet been
 called and will immediately return TRUE then.
 </para>
 
+<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
@@ -1353,16 +1576,6 @@ This function also works, if g_thread_init() has not yet been called.
 @Returns: the corresponding pointer
 
 
-<!-- ##### FUNCTION g_static_private_get_for_thread ##### -->
-<para>
-
-</para>
-
-@private_key: 
-@thread: 
-@Returns: 
-
-
 <!-- ##### FUNCTION g_static_private_set ##### -->
 <para>
 Sets the pointer keyed to @private_key for the current thread and the
@@ -1390,17 +1603,6 @@ g_private_new().
 current thread ends or sets this pointer again
 
 
-<!-- ##### FUNCTION g_static_private_set_for_thread ##### -->
-<para>
-
-</para>
-
-@private_key: 
-@thread: 
-@data: 
-@notify: 
-
-
 <!-- ##### FUNCTION g_static_private_free ##### -->
 <para>
 Releases all resources allocated to @private_key.