From 2395a333cc759f0f52165001b4802d14f9ffecc4 Mon Sep 17 00:00:00 2001 From: Sebastian Wilhelmi Date: Fri, 23 Feb 2001 16:42:48 +0000 Subject: [PATCH] Change the order to match the order in g_thread_create(). 2001-02-23 Sebastian Wilhelmi * gthread.h (struct _GThread): Change the order to match the order in g_thread_create(). * gthread.c (g_static_rec_mutex_lock_full): Also do the right thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a mutex, that is already locked. * glib/tmpl/threads.sgml: Big update. Almost ready. * glib/tmpl/async_queues.sgml: Typo. * glib/glib-sections.txt: Added g_static_rec_mutex_init, g_static_rec_mutex_free, g_static_rw_lock_init, g_static_private_init and g_static_private_free. * glib/glib-overrides.txt: Added g_thread_yield and g_thread_exit. --- ChangeLog | 9 + ChangeLog.pre-2-0 | 9 + ChangeLog.pre-2-10 | 9 + ChangeLog.pre-2-12 | 9 + ChangeLog.pre-2-2 | 9 + ChangeLog.pre-2-4 | 9 + ChangeLog.pre-2-6 | 9 + ChangeLog.pre-2-8 | 9 + docs/reference/ChangeLog | 12 + docs/reference/glib/glib-overrides.txt | 12 + docs/reference/glib/glib-sections.txt | 5 + docs/reference/glib/tmpl/async_queues.sgml | 2 +- docs/reference/glib/tmpl/threads.sgml | 484 ++++++++++++++++++++--------- glib/gthread.c | 10 +- glib/gthread.h | 4 +- gthread.c | 10 +- gthread.h | 4 +- 17 files changed, 467 insertions(+), 148 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87b5412..490be93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 87b5412..490be93 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,12 @@ +2001-02-23 Sebastian Wilhelmi + + * gthread.h (struct _GThread): Change the order to match the order + in g_thread_create(). + + * gthread.c (g_static_rec_mutex_lock_full): Also do the right + thing (behave like 'depth' calls to g_static_rec_mutex_lock) for a + mutex, that is already locked. + Thu Feb 22 10:31:36 2001 Owen Taylor * gmain.c (g_source_remove_poll): Add missing implementation diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 9b881ec..fd3aad8 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,15 @@ +2001-02-23 Sebastian Wilhelmi + + * glib/tmpl/threads.sgml: Big update. Almost ready. + + * glib/tmpl/async_queues.sgml: Typo. + + * glib/glib-sections.txt: Added g_static_rec_mutex_init, + g_static_rec_mutex_free, g_static_rw_lock_init, + g_static_private_init and g_static_private_free. + + * glib/glib-overrides.txt: Added g_thread_yield and g_thread_exit. + Fri Feb 16 06:52:20 2001 Tim Janik * gobject/tmpl/types.sgml: incorporated huge docu patch from Eric diff --git a/docs/reference/glib/glib-overrides.txt b/docs/reference/glib/glib-overrides.txt index e11bbb0..a1dce71 100644 --- a/docs/reference/glib/glib-overrides.txt +++ b/docs/reference/glib/glib-overrides.txt @@ -91,6 +91,18 @@ GStaticMutex* mutex GStaticMutex* mutex +# GThread + + +g_thread_yield +void + + + +g_thread_exit +void + + # G_LOCK_* macros diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 53c3c3f..a7b6948 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -479,15 +479,18 @@ G_UNLOCK GStaticRecMutex G_STATIC_REC_MUTEX_INIT +g_static_rec_mutex_init g_static_rec_mutex_lock g_static_rec_mutex_trylock g_static_rec_mutex_unlock g_static_rec_mutex_lock_full g_static_rec_mutex_unlock_full +g_static_rec_mutex_free GStaticRWLock G_STATIC_RW_LOCK_INIT +g_static_rw_lock_init g_static_rw_lock_reader_lock g_static_rw_lock_reader_trylock g_static_rw_lock_reader_unlock @@ -514,10 +517,12 @@ g_private_set GStaticPrivate G_STATIC_PRIVATE_INIT +g_static_private_init g_static_private_get g_static_private_get_for_thread g_static_private_set g_static_private_set_for_thread +g_static_private_free G_THREAD_ECF diff --git a/docs/reference/glib/tmpl/async_queues.sgml b/docs/reference/glib/tmpl/async_queues.sgml index 3e2926b..7a991cc 100644 --- a/docs/reference/glib/tmpl/async_queues.sgml +++ b/docs/reference/glib/tmpl/async_queues.sgml @@ -55,7 +55,7 @@ g_async_queue_unlock()) over multiple queue accessing instructions. This can be necessary to ensure the integrity of the queue, but should only be used, when really necessary as it can make your life harder if used unwisely. Normally you should only use the -locking function variants (those without the suffix _unlocking) +locking function variants (those without the suffix _unlocked) diff --git a/docs/reference/glib/tmpl/threads.sgml b/docs/reference/glib/tmpl/threads.sgml index 9a7cb14..2e23b2b 100644 --- a/docs/reference/glib/tmpl/threads.sgml +++ b/docs/reference/glib/tmpl/threads.sgml @@ -4,7 +4,8 @@ Threads -thread abstraction; including mutexes, conditions and thread private data. +thread abstraction; including threads, different mutexes, conditions +and thread private data. @@ -15,24 +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. 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 multithreaded 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). +(#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). + + +#GThreadPool +Thread pools. + + + +#GAsyncQueue +Send asynchronous messages between threads. + + + @@ -58,7 +72,7 @@ This macro is defined, if POSIX style threads are used. -This macro is defined, if the SOLARIS thread system is used. +This macro is defined, if the Solaris thread system is used. @@ -74,17 +88,18 @@ however provide one to g_thread_init() to make GLib multithread safe. - +The error domain of the GLib thread subsystem. - +Possible errors of thread related functions. -@G_THREAD_ERROR_AGAIN: +@G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource +shortage. Try again later. @@ -142,7 +157,8 @@ really know, what you are doing. g_thread_init() must not be called directly or indirectly as a -callback from GLib. +callback from GLib. Also no mutexes may be currently locked, while +calling g_thread_init(). @@ -182,7 +198,7 @@ libraries. @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 @@ -198,87 +214,168 @@ you can however use it as if it was a function. -@Returns: TRUE, if the thread system is initialized. +@Returns: TRUE, if the thread system is initialized - +Specifies the type of the @thread_func functions passed to +g_thread_create(). -@value: +@value: data supplied to the thread +Specifies the priority of a thread. + + + +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. + -@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 +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. + + + +Resources for a joinable thread are not fully released until +g_thread_join() is called for that thread. + -@priority: -@bound: -@joinable: +@joinable: is this thread joinable? +@bound: is this thread bound to a system thread? +@priority: the priority of the thread +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. + + +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. -@thread_func: -@arg: -@stack_size: -@joinable: -@bound: -@priority: -@error: -@Returns: + +The new thread executes the function @thread_func with the argument +@arg. If the thread was created successfully, it is returned. + + +@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. + - + +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. + + + +@thread_func: a function to execute in the new thread +@arg: 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 + + + +This functions returns the #GThread corresponding to the calling thread. -@Returns: +@Returns: the current thread - +Waits until @thread finishes, i.e. the function @thread_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(). -@thread: +@thread: a #GThread to be waited for +Change the priority of @thread to @priority. + + + +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. + -@thread: -@priority: +@thread: a #GThread +@priority: a new priority for @thread - + +Give way to other threads waiting to be scheduled. + + +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. - + +Exit the current thread. If another thread is waiting for that thread +using g_thread_join(), that thread will be woken up. + + + +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. + @@ -400,15 +497,15 @@ This function will abort, if g_thread_init() has not been called yet. -@Returns: a new #GMutex. +@Returns: a new #GMutex -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. @@ -418,20 +515,20 @@ called and will do nothing then. -#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 the #GMutex while calling g_mutex_lock(). Use +#GStaticRecMutex instead, if you need recursive mutexes. -@mutex: a #GMutex. +@mutex: a #GMutex -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. @@ -440,29 +537,32 @@ This function can also be used, if g_thread_init() has not yet been called and will immediately return TRUE then. -@mutex: a #GMutex. -@Returns: TRUE, if the #GMutex could be locked. +@mutex: a #GMutex +@Returns: TRUE, if @mutex could be locked -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. -@mutex: a #GMutex. + +This function can also be used, if g_thread_init() has not yet been +called and will do nothing then. + + +@mutex: a #GMutex -Destroys the #GMutex. +Destroys @mutex. -@mutex: a #GMutex. +@mutex: a #GMutex @@ -475,17 +575,6 @@ safer version of our give_me_next_number() example: -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. - - - Using GStaticMutex to simplify thread-safe programming @@ -505,13 +594,25 @@ up any allocated recourses. +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. + + + Even though #GStaticMutex is not opaque, it should only be used with the following functions, as it is defined differently on different platforms. -All of the g_static_mutex_* functions can also be used, if -g_thread_init() has not yet. + +All of the g_static_mutex_* functions can also be used, if +g_thread_init() has not yet been called. @@ -533,24 +634,22 @@ g_static_mutex_init(). - -Initializing a GStaticMutext + GStaticMutex my_mutex = G_STATIC_MUTEX_INIT; - + -A #GStaticMutex must be initialized with this function, before it can -be used. Alternatively you can initialize it with +Initializes @mutex. Alternatively you can initialize it with #G_STATIC_MUTEX_INIT. -@mutex: a #GStaticMutex to be initialized. +@mutex: a #GStaticMutex to be initialized @@ -558,7 +657,7 @@ be used. Alternatively you can initialize it with works like g_mutex_lock(), but for a #GStaticMutex. -@mutex: a #GStaticMutex. +@mutex: a #GStaticMutex @@ -567,8 +666,8 @@ works like g_mutex_lock(), but for a #GStaticMutex. works like g_mutex_trylock(), but for a #GStaticMutex. -@mutex: a #GStaticMutex. -@Returns: TRUE, if the #GStaticMutex could be locked. +@mutex: a #GStaticMutex +@Returns: TRUE, if the #GStaticMutex could be locked @@ -577,7 +676,7 @@ works like g_mutex_trylock(), but for a #GStaticMutex. works like g_mutex_unlock(), but for a #GStaticMutex. -@mutex: a #GStaticMutex. +@mutex: a #GStaticMutex @@ -585,23 +684,26 @@ works like g_mutex_unlock(), but for a #GStaticMutex. 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. -@mutex: a #GStaticMutex. -@Returns: the corresponding #GMutex. +@mutex: a #GStaticMutex +@Returns: the #GMutex corresponding to @mutex -Releases all resources allocated to a #GStaticMutex. 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. +Releases all resources allocated to @mutex. -@mutex: a #GStaticMutex. + +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. + + +@mutex: a #GStaticMutex to be freed @@ -610,8 +712,8 @@ the #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 @@ -639,7 +741,7 @@ int give_me_next_number () -@name: the name of the lock. +@name: the name of the lock @@ -648,7 +750,7 @@ int give_me_next_number () This works like #G_LOCK_DEFINE, but it creates a static object. -@name: the name of the lock. +@name: the name of the lock @@ -657,7 +759,7 @@ 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. -@name: the name of the lock. +@name: the name of the lock @@ -666,7 +768,7 @@ This declares a lock, that is defined with #G_LOCK_DEFINE in another module. works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE. -@name: the name of the lock. +@name: the name of the lock @@ -675,8 +777,8 @@ works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE. works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE. -@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 @@ -685,12 +787,28 @@ works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE. works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE. -@name: the name of the lock. +@name: the name of the lock +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(). + + + +Even though #GStaticRecMutex is not opaque, it should only be used with +the following functions. + + +All of the g_static_rec_mutex_* functions can also be used, if +g_thread_init() has not been called. @mutex: @@ -699,52 +817,104 @@ works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE. +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(). + + + + + +GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT; + + + + + + + +A #GStaticRecMutex must be initialized with this function, before it +can be used. Alternatively you can initialize it with +#G_STATIC_REC_MUTEX_INIT. +@mutex: a #GStaticRecMutex to be initialized - +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. -@mutex: +@mutex: a #GStaticRecMutex to lock - +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. -@mutex: -@Returns: +@mutex: a #GStaticRecMutex to lock +@Returns: TRUE, if @mutex could be locked - +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. -@mutex: +@mutex: a #GStaticRecMutex to unlock - +Works like calling g_static_rec_mutex_lock() for @mutex n times. -@mutex: -@depth: +@mutex: a #GStaticRecMutex to lock +@depth: number of times this mutex has to be unlocked to be completely unlocked +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. + + +@mutex: a #GStaticRecMutex to completely unlock +@Returns: number of times @mutex has been locked by the current thread + + + +Releases all resources allocated to a #GStaticRecMutex. -@mutex: -@Returns: + +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. + + +@mutex: a #GStaticRecMutex to be freed @@ -766,6 +936,14 @@ works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE. + + + + + +@lock: + + @@ -903,7 +1081,7 @@ Creates a new #GCond. This function will abort, if g_thread_init() has not been called yet. -@Returns: a new #GCond. +@Returns: a new #GCond @@ -918,7 +1096,7 @@ This function can also be used, if g_thread_init() has not yet been called and will do nothing then. -@cond: a #GCond. +@cond: a #GCond @@ -934,14 +1112,14 @@ This function can also be used, if g_thread_init() has not yet been called and will do nothing then. -@cond: a #GCond. +@cond: a #GCond -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. @@ -949,15 +1127,15 @@ This function can also be used, if g_thread_init() has not yet been called and will immediately return then. -@cond: a #GCond. -@mutex: the #GMutex, that is currently locked. +@cond: a #GCond +@mutex: a #GMutex, that is currently locked -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. @@ -970,10 +1148,10 @@ This function can also be used, if g_thread_init() has not yet been called and will immediately return TRUE then. -@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. +@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 @@ -982,7 +1160,7 @@ called and will immediately return TRUE then. Destroys the #GCond. -@cond: a #GCond. +@cond: a #GCond @@ -1048,15 +1226,15 @@ destructor is called with this pointer as the argument. -The @destructor is working quite differently from @notify in +@destructor is working quite differently from @notify in g_static_private_set(). -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. @@ -1067,8 +1245,8 @@ This function will abort, if g_thread_init() has not been called yet. @destructor: a function to handle the data keyed to #GPrivate, when a -thread ends. -@Returns: +thread ends +@Returns: a new #GPrivate @@ -1084,8 +1262,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. -@private_key: a #GPrivate. -@Returns: the corresponding pointer. +@private_key: a #GPrivate +@Returns: the corresponding pointer @@ -1099,8 +1277,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. -@private_key: a #GPrivate. -@data: the new pointer. +@private_key: a #GPrivate +@data: the new pointer @@ -1153,6 +1331,15 @@ GStaticPrivate my_private = G_STATIC_PRIVATE_INIT; + + +Initializes @private_key. Alternatively you can initialize it with +#G_STATIC_PRIVATE_INIT. + + +@private_key: a #GStaticPrivate to be initialized + + Works like g_private_get() only for a #GStaticPrivate. @@ -1162,8 +1349,8 @@ Works like g_private_get() only for a #GStaticPrivate. This function also works, if g_thread_init() has not yet been called. -@private_key: a #GStaticPrivate. -@Returns: the corresponding pointer. +@private_key: a #GStaticPrivate +@Returns: the corresponding pointer @@ -1192,15 +1379,15 @@ called g_thread_init(). -The @notify is working quite differently from @destructor in +@notify is working quite differently from @destructor in g_private_new(). -@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 @@ -1214,3 +1401,18 @@ current thread ends or sets this pointer again. @notify: + + +Releases all resources allocated to @private_key. + + + +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. + + +@private_key: a #GStaticPrivate to be freed + + diff --git a/glib/gthread.c b/glib/gthread.c index 20aa3eb..4393e8d 100644 --- a/glib/gthread.c +++ b/glib/gthread.c @@ -292,13 +292,21 @@ void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, guint depth) { + GSystemThread self; g_return_if_fail (mutex); if (!g_thread_supported ()) return; + G_THREAD_UF (thread_self, (&self)); + + if (g_system_thread_equal (self, mutex->owner)) + { + mutex->depth += depth; + return; + } g_static_mutex_lock (&mutex->mutex); - G_THREAD_UF (thread_self, (&mutex->owner)); + g_system_thread_assign (mutex->owner, self); mutex->depth = depth; } diff --git a/glib/gthread.h b/glib/gthread.h index 3452af4..098cfc4 100644 --- a/glib/gthread.h +++ b/glib/gthread.h @@ -56,9 +56,9 @@ typedef enum typedef struct _GThread GThread; struct _GThread { - GThreadPriority priority; - gboolean bound; gboolean joinable; + gboolean bound; + GThreadPriority priority; }; typedef struct _GMutex GMutex; diff --git a/gthread.c b/gthread.c index 20aa3eb..4393e8d 100644 --- a/gthread.c +++ b/gthread.c @@ -292,13 +292,21 @@ void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, guint depth) { + GSystemThread self; g_return_if_fail (mutex); if (!g_thread_supported ()) return; + G_THREAD_UF (thread_self, (&self)); + + if (g_system_thread_equal (self, mutex->owner)) + { + mutex->depth += depth; + return; + } g_static_mutex_lock (&mutex->mutex); - G_THREAD_UF (thread_self, (&mutex->owner)); + g_system_thread_assign (mutex->owner, self); mutex->depth = depth; } diff --git a/gthread.h b/gthread.h index 3452af4..098cfc4 100644 --- a/gthread.h +++ b/gthread.h @@ -56,9 +56,9 @@ typedef enum typedef struct _GThread GThread; struct _GThread { - GThreadPriority priority; - gboolean bound; gboolean joinable; + gboolean bound; + GThreadPriority priority; }; typedef struct _GMutex GMutex; -- 2.7.4