Software: Apache/2.0.54 (Fedora). PHP/5.0.4 uname -a: Linux mina-info.me 2.6.17-1.2142_FC4smp #1 SMP Tue Jul 11 22:57:02 EDT 2006 i686 uid=48(apache) gid=48(apache) groups=48(apache) Safe-mode: OFF (not secure) /usr/share/gtk-doc/html/glib/ drwxr-xr-x |
Viewing file: Select action/file-type:
Synopsis#include <glib.h> #define G_THREADS_ENABLED #define G_THREADS_IMPL_POSIX #define G_THREADS_IMPL_SOLARIS #define G_THREADS_IMPL_NONE #define G_THREAD_ERROR enum GThreadError; GThreadFunctions; void g_thread_init (GThreadFunctions *vtable); gboolean g_thread_supported (); gpointer (*GThreadFunc) (gpointer data); enum GThreadPriority; GThread; GThread* g_thread_create (GThreadFunc func, gpointer data, gboolean joinable, GError **error); GThread* g_thread_create_full (GThreadFunc func, gpointer data, gulong stack_size, gboolean joinable, gboolean bound, GThreadPriority priority, GError **error); GThread* g_thread_self (void); gpointer g_thread_join (GThread *thread); void g_thread_set_priority (GThread *thread, GThreadPriority priority); void g_thread_yield (); void g_thread_exit (gpointer retval); GMutex; GMutex* g_mutex_new (); void g_mutex_lock (GMutex *mutex); gboolean g_mutex_trylock (GMutex *mutex); void g_mutex_unlock (GMutex *mutex); void g_mutex_free (GMutex *mutex); GStaticMutex; #define G_STATIC_MUTEX_INIT void g_static_mutex_init (GStaticMutex *mutex); void g_static_mutex_lock (GStaticMutex *mutex); gboolean g_static_mutex_trylock (GStaticMutex *mutex); void g_static_mutex_unlock (GStaticMutex *mutex); GMutex* g_static_mutex_get_mutex (GStaticMutex *mutex); void g_static_mutex_free (GStaticMutex *mutex); #define G_LOCK_DEFINE (name) #define G_LOCK_DEFINE_STATIC (name) #define G_LOCK_EXTERN (name) #define G_LOCK (name) #define G_TRYLOCK (name) #define G_UNLOCK (name) GStaticRecMutex; #define G_STATIC_REC_MUTEX_INIT void g_static_rec_mutex_init (GStaticRecMutex *mutex); void g_static_rec_mutex_lock (GStaticRecMutex *mutex); gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex); void g_static_rec_mutex_unlock (GStaticRecMutex *mutex); void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, guint depth); guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex); void g_static_rec_mutex_free (GStaticRecMutex *mutex); GStaticRWLock; #define G_STATIC_RW_LOCK_INIT void g_static_rw_lock_init (GStaticRWLock *lock); void g_static_rw_lock_reader_lock (GStaticRWLock *lock); gboolean g_static_rw_lock_reader_trylock (GStaticRWLock *lock); void g_static_rw_lock_reader_unlock (GStaticRWLock *lock); void g_static_rw_lock_writer_lock (GStaticRWLock *lock); gboolean g_static_rw_lock_writer_trylock (GStaticRWLock *lock); void g_static_rw_lock_writer_unlock (GStaticRWLock *lock); void g_static_rw_lock_free (GStaticRWLock *lock); GCond; GCond* g_cond_new (); void g_cond_signal (GCond *cond); void g_cond_broadcast (GCond *cond); void g_cond_wait (GCond *cond, GMutex *mutex); gboolean g_cond_timed_wait (GCond *cond, GMutex *mutex, GTimeVal *abs_time); void g_cond_free (GCond *cond); GPrivate; GPrivate* g_private_new (GDestroyNotify destructor); gpointer g_private_get (GPrivate *private_key); void g_private_set (GPrivate *private_key, gpointer data); GStaticPrivate; #define G_STATIC_PRIVATE_INIT void g_static_private_init (GStaticPrivate *private_key); gpointer g_static_private_get (GStaticPrivate *private_key); void g_static_private_set (GStaticPrivate *private_key, gpointer data, GDestroyNotify notify); void g_static_private_free (GStaticPrivate *private_key); GOnce; enum GOnceStatus; #define G_ONCE_INIT #define g_once (once, func, arg) DescriptionThreads act almost like processes, but unlike processes all threads of one process share the same memory. This is good, as it provides easy 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 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 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 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). DetailsG_THREADS_ENABLED#define G_THREADS_ENABLED
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_THREADS_IMPL_POSIX#define G_THREADS_IMPL_POSIX This macro is defined, if POSIX style threads are used. G_THREADS_IMPL_SOLARIS#define G_THREADS_IMPL_SOLARIS This macro is defined, if the Solaris thread system is used. G_THREADS_IMPL_NONE#define G_THREADS_IMPL_NONE
This macro is defined, if no thread implementation is used. You can
however provide one to G_THREAD_ERROR#define G_THREAD_ERROR g_thread_error_quark () The error domain of the GLib thread subsystem. enum GThreadErrortypedef enum { G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ } GThreadError; Possible errors of thread related functions.
GThreadFunctionstypedef struct { GMutex* (*mutex_new) (void); void (*mutex_lock) (GMutex *mutex); gboolean (*mutex_trylock) (GMutex *mutex); void (*mutex_unlock) (GMutex *mutex); void (*mutex_free) (GMutex *mutex); GCond* (*cond_new) (void); void (*cond_signal) (GCond *cond); void (*cond_broadcast) (GCond *cond); void (*cond_wait) (GCond *cond, GMutex *mutex); gboolean (*cond_timed_wait) (GCond *cond, GMutex *mutex, GTimeVal *end_time); void (*cond_free) (GCond *cond); GPrivate* (*private_new) (GDestroyNotify destructor); gpointer (*private_get) (GPrivate *private_key); void (*private_set) (GPrivate *private_key, gpointer data); void (*thread_create) (GThreadFunc func, gpointer data, gulong stack_size, gboolean joinable, gboolean bound, GThreadPriority priority, gpointer thread, GError **error); void (*thread_yield) (void); void (*thread_join) (gpointer thread); void (*thread_exit) (void); void (*thread_set_priority)(gpointer thread, GThreadPriority priority); void (*thread_self) (gpointer thread); gboolean (*thread_equal) (gpointer thread1, gpointer thread2); } GThreadFunctions;
This function table is used by NoteThis struct should only be used, if you know, what you are doing. g_thread_init ()void g_thread_init (GThreadFunctions *vtable);
If you use GLib from more than one thread, you must initialize
the thread system by calling Note
You should only call Note
if (!g_thread_supported ()) g_thread_init (NULL);
After that line either the thread system is initialized or the program will abort, if no thread system is available in GLib, i.e. either G_THREADS_ENABLED is not defined or G_THREADS_IMPL_NONE is defined.
If no thread system is available and Note
To use
g_thread_supported ()gboolean g_thread_supported (); This function returns, whether the thread system is initialized or not. NoteThis function is actually a macro. Apart from taking the address of it you can however use it as if it was a function.
GThreadFunc ()gpointer (*GThreadFunc) (gpointer data);
Specifies the type of the
enum GThreadPrioritytypedef enum { G_THREAD_PRIORITY_LOW, G_THREAD_PRIORITY_NORMAL, G_THREAD_PRIORITY_HIGH, G_THREAD_PRIORITY_URGENT } GThreadPriority; Specifies the priority of a thread. NoteIt is not guaranteed, that threads with different priorities really behave accordingly. On some systems (e.g. Linux) there are no thread 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.
GThreadtypedef struct { } GThread; 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. Note
Resources for a joinable thread are not fully released until
g_thread_create ()GThread* g_thread_create (GThreadFunc func, gpointer data, gboolean joinable, GError **error); This function creates a new thread with the default priority.
If
The new thread executes the function
g_thread_create_full ()GThread* g_thread_create_full (GThreadFunc func, gpointer data, gulong stack_size, gboolean joinable, gboolean bound, GThreadPriority priority, GError **error);
This function creates a new thread with the priority
If
The new thread executes the function
Note
It is not guaranteed, that threads with different priorities really
behave accordingly. On some systems (e.g. Linux) there are no thread
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 Note
Only use
g_thread_self ()GThread* g_thread_self (void); This functions returns the GThread corresponding to the calling thread.
g_thread_join ()gpointer g_thread_join (GThread *thread);
Waits until
g_thread_set_priority ()void g_thread_set_priority (GThread *thread, GThreadPriority priority);
Changes the priority of NoteIt is not guaranteed, that threads with different priorities really behave accordingly. On some systems (e.g. Linux) there are no thread 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_yield ()void g_thread_yield (); Gives 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. g_thread_exit ()void g_thread_exit (gpointer retval);
Exits the current thread. If another thread is waiting for that thread
using
g_thread_exit (retval);
is equivalent to calling
return retval;
in the function Note
Never call
GMutextypedef struct _GMutex GMutex; The GMutex struct is an opaque data structure to represent a mutex (mutual exclusion). It can be used to protect data against shared access. Take for example the following function: Example 3. A function which will not work in a threaded environment int give_me_next_number () { static int current_number = 0; /* now do a very complicated calculation to calculate the new number, this might for example be a random number generator */ current_number = calc_next_number (current_number); return current_number; }
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:
Example 4. The wrong way to write a thread-safe function int give_me_next_number () { static int current_number = 0; int ret_val; static GMutex * mutex = NULL; if (!mutex) mutex = g_mutex_new (); g_mutex_lock (mutex); ret_val = current_number = calc_next_number (current_number); g_mutex_unlock (mutex); return ret_val; }
This looks like it would work, but there is a race condition while constructing the mutex and this code cannot work reliable. So please do not use such constructs in your own programs. One working solution is:
Example 5. A correct thread-safe function static GMutex *give_me_next_number_mutex = NULL; /* this function must be called before any call to give_me_next_number () it must be called exactly once. */ void init_give_me_next_number () { g_assert (give_me_next_number_mutex == NULL); give_me_next_number_mutex = g_mutex_new (); } int give_me_next_number () { static int current_number = 0; int ret_val; g_mutex_lock (give_me_next_number_mutex); ret_val = current_number = calc_next_number (current_number); g_mutex_unlock (give_me_next_number_mutex); return ret_val; }
GStaticMutex provides a simpler and safer way of doing this.
If you want to use a mutex, but your code should also work without
calling A GMutex should only be accessed via the following functions. Note
All of the g_mutex_new ()GMutex* g_mutex_new (); Creates a new GMutex. Note
This function will abort, if
g_mutex_lock ()void g_mutex_lock (GMutex *mutex);
Locks
This function can also be used, if Note
GMutex is neither guaranteed to be recursive nor to be non-recursive,
i.e. a thread could deadlock while calling
g_mutex_trylock ()gboolean g_mutex_trylock (GMutex *mutex);
Tries to lock
This function can also be used, if Note
GMutex is neither guaranteed to be recursive nor to be non-recursive,
i.e. the return value of
g_mutex_unlock ()void g_mutex_unlock (GMutex *mutex);
Unlocks
This function can also be used, if
GStaticMutextypedef struct _GStaticMutex GStaticMutex;
A GStaticMutex works like a GMutex, but it has one significant
advantage. It doesn't need to be created at run-time like a GMutex,
but can be defined at compile-time. Here is a shorter, easier and
safer version of our
Example 6. Using GStaticMutex to simplify thread-safe programming int give_me_next_number () { static int current_number = 0; int ret_val; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); ret_val = current_number = calc_next_number (current_number); g_static_mutex_unlock (&mutex); return ret_val; }
Sometimes you would like to dynamically create a mutex. If you don't
want to require prior calling to 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 Note
All of the G_STATIC_MUTEX_INIT#define G_STATIC_MUTEX_INIT
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
GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;
g_static_mutex_init ()void g_static_mutex_init (GStaticMutex *mutex);
Initializes
g_static_mutex_lock ()void g_static_mutex_lock (GStaticMutex *mutex);
Works like
g_static_mutex_trylock ()gboolean g_static_mutex_trylock (GStaticMutex *mutex);
Works like
g_static_mutex_unlock ()void g_static_mutex_unlock (GStaticMutex *mutex);
Works like
g_static_mutex_get_mutex ()GMutex* g_static_mutex_get_mutex (GStaticMutex *mutex);
For some operations (like
g_static_mutex_free ()void g_static_mutex_free (GStaticMutex *mutex);
Releases all resources allocated to 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.
G_LOCK_DEFINE()#define G_LOCK_DEFINE(name)
The
Example 7. Using the G_LOCK_DEFINE (current_number); int give_me_next_number () { static int current_number = 0; int ret_val; G_LOCK (current_number); ret_val = current_number = calc_next_number (current_number); G_UNLOCK (current_number); return ret_val; }
G_LOCK_DEFINE_STATIC()#define G_LOCK_DEFINE_STATIC(name) This works like G_LOCK_DEFINE, but it creates a static object.
G_LOCK_EXTERN()#define G_LOCK_EXTERN(name) This declares a lock, that is defined with G_LOCK_DEFINE in another module.
G_LOCK()#define G_LOCK(name)
Works like
G_TRYLOCK()#define G_TRYLOCK(name)
Works like
G_UNLOCK()#define G_UNLOCK(name)
Works like
GStaticRecMutextypedef struct { } GStaticRecMutex;
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 Even though GStaticRecMutex is not opaque, it should only be used with the following functions.
All of the G_STATIC_REC_MUTEX_INIT#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
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
GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;
g_static_rec_mutex_init ()void g_static_rec_mutex_init (GStaticRecMutex *mutex); A GStaticRecMutex must be initialized with this function, before it can be used. Alternatively you can initialize it with G_STATIC_REC_MUTEX_INIT.
g_static_rec_mutex_lock ()void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
Locks
g_static_rec_mutex_trylock ()gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
Tries to lock
g_static_rec_mutex_unlock ()void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
Unlocks
g_static_rec_mutex_lock_full ()void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, guint depth);
Works like calling
g_static_rec_mutex_unlock_full ()guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
Completely unlocks
g_static_rec_mutex_free ()void g_static_rec_mutex_free (GStaticRecMutex *mutex); Releases all resources allocated to a GStaticRecMutex. 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.
GStaticRWLocktypedef struct { } GStaticRWLock; 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 8. An array with access functions 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); }
This example shows an array, which can be accessed by many readers
(the 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. Even though GStaticRWLock is not opaque, it should only be used with the following functions.
All of the Note
A read-write lock has a higher overhead as a mutex. For example both
G_STATIC_RW_LOCK_INIT#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }
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
GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;
g_static_rw_lock_init ()void g_static_rw_lock_init (GStaticRWLock *lock); A GStaticRWLock must be initialized with this function, before it can be used. Alternatively you can initialize it with G_STATIC_RW_LOCK_INIT.
g_static_rw_lock_reader_lock ()void g_static_rw_lock_reader_lock (GStaticRWLock *lock);
Locks GStaticRWLock is not recursive. It might seem to be possible to recursively lock for reading, but that can result in a deadlock as well, due to writer preference.
g_static_rw_lock_reader_trylock ()gboolean g_static_rw_lock_reader_trylock (GStaticRWLock *lock);
Tries to lock
g_static_rw_lock_reader_unlock ()void g_static_rw_lock_reader_unlock (GStaticRWLock *lock);
Unlocks
g_static_rw_lock_writer_lock ()void g_static_rw_lock_writer_lock (GStaticRWLock *lock);
Locks
g_static_rw_lock_writer_trylock ()gboolean g_static_rw_lock_writer_trylock (GStaticRWLock *lock);
Tries to lock
g_static_rw_lock_writer_unlock ()void g_static_rw_lock_writer_unlock (GStaticRWLock *lock);
Unlocks
g_static_rw_lock_free ()void g_static_rw_lock_free (GStaticRWLock *lock);
Releases all resources allocated to 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.
GCondtypedef struct _GCond GCond; The GCond struct is an opaque data structure to represent a condition. A GCond is an object, that threads can block on, if they find a certain condition to be false. If other threads change the state of this condition they can signal the GCond, such that the waiting thread is woken up.
Example 9. Using GCond to block a thread until a condition is satisfied GCond* data_cond = NULL; /* Must be initialized somewhere */ GMutex* data_mutex = NULL; /* Must be initialized somewhere */ gpointer current_data = NULL; void push_data (gpointer data) { g_mutex_lock (data_mutex); current_data = data; g_cond_signal (data_cond); g_mutex_unlock (data_mutex); } gpointer pop_data () { gpointer data; g_mutex_lock (data_mutex); while (!current_data) g_cond_wait (data_cond, data_mutex); data = current_data; current_data = NULL; g_mutex_unlock (data_mutex); return data; }
Whenever a thread calls Note
It is important to use the A GCond should only be accessed via the following functions. Note
All of the g_cond_new ()GCond* g_cond_new ();
Creates a new GCond. This function will abort, if
g_cond_signal ()void g_cond_signal (GCond *cond);
If threads are waiting for
This function can also be used, if
g_cond_broadcast ()void g_cond_broadcast (GCond *cond);
If threads are waiting for
This function can also be used, if
g_cond_wait ()void g_cond_wait (GCond *cond, GMutex *mutex);
Waits until this thread is woken up on
This function can also be used, if g_cond_timed_wait ()gboolean g_cond_timed_wait (GCond *cond, GMutex *mutex, GTimeVal *abs_time);
Waits until this thread is woken up on
If
This function can also be used, if
To easily calculate GPrivatetypedef struct _GPrivate GPrivate;
The GPrivate struct is an opaque data structure to represent a thread
private data key. Threads can thereby obtain and set a pointer, which
is private to the current thread.
Take our Example 10. Using GPrivate for per-thread data GPrivate* current_number_key = NULL; /* Must be initialized somewhere */ /* with g_private_new (g_free); */ int give_me_next_number () { int *current_number = g_private_get (current_number_key); if (!current_number) { current_number = g_new (int,1); *current_number = 0; g_private_set (current_number_key, current_number); } *current_number = calc_next_number (*current_number); return *current_number; }
Here the pointer belonging to the key The GPrivate struct should only be accessed via the following functions. Note
All of the g_private_new ()GPrivate* g_private_new (GDestroyNotify destructor);
Creates a new GPrivate. If Note
NoteA GPrivate can not be freed. Reuse it instead, if you can to avoid shortage or use GStaticPrivate. Note
This function will abort, if g_private_get ()gpointer g_private_get (GPrivate *private_key);
Returns the pointer keyed to
This function can also be used, if
g_private_set ()void g_private_set (GPrivate *private_key, gpointer data);
Sets the pointer keyed to
This function can also be used, if
GStaticPrivatetypedef struct { } GStaticPrivate;
A GStaticPrivate works almost like a GPrivate, but it has one
significant advantage. It doesn't need to be created at run-time like
a GPrivate, but can be defined at compile-time. This is similar to
the difference between GMutex and GStaticMutex. Now look at our
Example 11. Using GStaticPrivate for per-thread data int give_me_next_number () { static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT; int *current_number = g_static_private_get (¤t_number_key); if (!current_number) { current_number = g_new (int,1); *current_number = 0; g_static_private_set (¤t_number_key, current_number, g_free); } *current_number = calc_next_number (*current_number); return *current_number; }
G_STATIC_PRIVATE_INIT#define G_STATIC_PRIVATE_INIT Every GStaticPrivate must be initialized with this macro, before it can be used.
GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;
g_static_private_init ()void g_static_private_init (GStaticPrivate *private_key);
Initializes
g_static_private_get ()gpointer g_static_private_get (GStaticPrivate *private_key);
Works like
This function also works, if
g_static_private_set ()void g_static_private_set (GStaticPrivate *private_key, gpointer data, GDestroyNotify notify);
Sets the pointer keyed to
This function also works, if Note
g_static_private_free ()void g_static_private_free (GStaticPrivate *private_key);
Releases all resources allocated to 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.
GOncetypedef struct { volatile GOnceStatus status; volatile gpointer retval; } GOnce; A GOnce struct controls a one-time initialization function. Any one-time initialization function must have its own unique GOnce struct. Since 2.4 enum GOnceStatustypedef enum { G_ONCE_STATUS_NOTCALLED, G_ONCE_STATUS_PROGRESS, G_ONCE_STATUS_READY } GOnceStatus; The possible stati of a one-time initialization function controlled by a GOnce struct.
Since 2.4 G_ONCE_INIT#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL } A GOnce must be initialized with this macro, before it can be used.
GOnce my_once = G_ONCE_INIT;
Since 2.4 g_once()#define g_once(once, func, arg)
The first call to this routine by a process with a given GOnce struct calls
For example, a mutex or a thread-specific data key must be created exactly once. In a threaded
environment, calling
gpointer
Since 2.4
|
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #16 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0038 ]-- |