00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef __G_THREAD_H__
00029 #define __G_THREAD_H__
00030
00031 #include <_ansi.h>
00032 #include <glib/gerror.h>
00033 #include <glib/gtypes.h>
00034 #include <glib/gatomic.h>
00035
00036 G_BEGIN_DECLS
00037
00038
00039
00040 #ifdef SYMBIAN
00041 IMPORT_C GQuark g_thread_error_quark (void);
00042 #else
00043 extern GQuark g_thread_error_quark (void);
00044 #endif
00045 #define G_THREAD_ERROR g_thread_error_quark ()
00046
00047 typedef enum
00048 {
00049 G_THREAD_ERROR_AGAIN
00050 } GThreadError;
00051
00052 typedef gpointer (*GThreadFunc) (gpointer data);
00053
00054 typedef enum
00055 {
00056 G_THREAD_PRIORITY_LOW,
00057 G_THREAD_PRIORITY_NORMAL,
00058 G_THREAD_PRIORITY_HIGH,
00059 G_THREAD_PRIORITY_URGENT
00060 } GThreadPriority;
00061
00062 typedef struct _GThread GThread;
00063 struct _GThread
00064 {
00065
00066 GThreadFunc func;
00067 gpointer data;
00068 gboolean joinable;
00069 GThreadPriority priority;
00070 };
00071
00072 typedef struct _GMutex GMutex;
00073 typedef struct _GCond GCond;
00074 typedef struct _GPrivate GPrivate;
00075 typedef struct _GStaticPrivate GStaticPrivate;
00076
00077 typedef struct _GThreadFunctions GThreadFunctions;
00078 struct _GThreadFunctions
00079 {
00080 GMutex* (*mutex_new) (void);
00081 void (*mutex_lock) (GMutex *mutex);
00082 gboolean (*mutex_trylock) (GMutex *mutex);
00083 void (*mutex_unlock) (GMutex *mutex);
00084 void (*mutex_free) (GMutex *mutex);
00085 GCond* (*cond_new) (void);
00086 void (*cond_signal) (GCond *cond);
00087 void (*cond_broadcast) (GCond *cond);
00088 void (*cond_wait) (GCond *cond,
00089 GMutex *mutex);
00090 gboolean (*cond_timed_wait) (GCond *cond,
00091 GMutex *mutex,
00092 GTimeVal *end_time);
00093 void (*cond_free) (GCond *cond);
00094 GPrivate* (*private_new) (GDestroyNotify destructor);
00095 gpointer (*private_get) (GPrivate *private_key);
00096 void (*private_set) (GPrivate *private_key,
00097 gpointer data);
00098 void (*thread_create) (GThreadFunc func,
00099 gpointer data,
00100 gulong stack_size,
00101 gboolean joinable,
00102 gboolean bound,
00103 GThreadPriority priority,
00104 gpointer thread,
00105 GError **error);
00106 void (*thread_yield) (void);
00107 void (*thread_join) (gpointer thread);
00108 void (*thread_exit) (void);
00109 void (*thread_set_priority)(gpointer thread,
00110 GThreadPriority priority);
00111 void (*thread_self) (gpointer thread);
00112 gboolean (*thread_equal) (gpointer thread1,
00113 gpointer thread2);
00114 };
00115
00116 #ifdef SYMBIAN
00117 IMPORT_C GThreadFunctions *_g_thread_functions_for_glib_use();
00118 #endif
00119 GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use;
00120
00121 #ifdef SYMBIAN
00122 IMPORT_C gboolean *_g_thread_use_default_impl();
00123 #endif
00124 GLIB_VAR gboolean g_thread_use_default_impl;
00125
00126 #ifdef SYMBIAN
00127 IMPORT_C gboolean *_g_threads_got_initialized();
00128 #endif
00129 GLIB_VAR gboolean g_threads_got_initialized;
00130
00131
00132
00133
00134
00135 IMPORT_C void g_thread_init (GThreadFunctions *vtable);
00136
00137 #ifdef SYMBIAN
00138 IMPORT_C gboolean g_thread_supported();
00139 #else
00140 #define g_thread_supported() (g_threads_got_initialized)
00141 #endif
00142
00143
00144
00145
00146
00147
00148
00149
00150 IMPORT_C void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
00151
00152
00153 #define G_MUTEX_DEBUG_MAGIC 0xf8e18ad7
00154
00155 #ifdef G_ERRORCHECK_MUTEXES
00156 #define g_thread_init(vtable) g_thread_init_with_errorcheck_mutexes (vtable)
00157 #endif
00158
00159
00160 IMPORT_C GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
00161
00162 #define g_static_mutex_get_mutex_impl_shortcut(mutex) \
00163 (g_atomic_pointer_get ((gpointer*)(void*)mutex) ? *(mutex) : \
00164 g_static_mutex_get_mutex_impl (mutex))
00165
00166
00167
00168 #define G_THREAD_UF(op, arglist) \
00169 (*g_thread_functions_for_glib_use . op) arglist
00170 #define G_THREAD_CF(op, fail, arg) \
00171 (g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
00172 #define G_THREAD_ECF(op, fail, mutex, type) \
00173 (g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
00174 (*g_thread_functions_for_glib_use . op)) \
00175 (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
00176
00177 #ifndef G_ERRORCHECK_MUTEXES
00178 # define g_mutex_lock(mutex) \
00179 G_THREAD_CF (mutex_lock, (void)0, (mutex))
00180 # define g_mutex_trylock(mutex) \
00181 G_THREAD_CF (mutex_trylock, TRUE, (mutex))
00182 # define g_mutex_unlock(mutex) \
00183 G_THREAD_CF (mutex_unlock, (void)0, (mutex))
00184 # define g_mutex_free(mutex) \
00185 G_THREAD_CF (mutex_free, (void)0, (mutex))
00186 # define g_cond_wait(cond, mutex) \
00187 G_THREAD_CF (cond_wait, (void)0, (cond, mutex))
00188 # define g_cond_timed_wait(cond, mutex, abs_time) \
00189 G_THREAD_CF (cond_timed_wait, TRUE, (cond, mutex, abs_time))
00190 #else
00191 # define g_mutex_lock(mutex) \
00192 G_THREAD_ECF (mutex_lock, (void)0, (mutex), void)
00193 # define g_mutex_trylock(mutex) \
00194 G_THREAD_ECF (mutex_trylock, TRUE, (mutex), gboolean)
00195 # define g_mutex_unlock(mutex) \
00196 G_THREAD_ECF (mutex_unlock, (void)0, (mutex), void)
00197 # define g_mutex_free(mutex) \
00198 G_THREAD_ECF (mutex_free, (void)0, (mutex), void)
00199 # define g_cond_wait(cond, mutex) \
00200 (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\
00201 g_thread_functions_for_glib_use.cond_wait) \
00202 (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0)
00203 # define g_cond_timed_wait(cond, mutex, abs_time) \
00204 (g_thread_supported () ? \
00205 ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*)) \
00206 g_thread_functions_for_glib_use.cond_timed_wait) \
00207 (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE)
00208 #endif
00209
00210 #define g_mutex_new() G_THREAD_UF (mutex_new, ())
00211 #define g_cond_new() G_THREAD_UF (cond_new, ())
00212 #define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
00213 #define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
00214 #define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
00215 #define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
00216 #define g_private_get(private_key) G_THREAD_CF (private_get, \
00217 ((gpointer)private_key), \
00218 (private_key))
00219 #define g_private_set(private_key, value) G_THREAD_CF (private_set, \
00220 (void) (private_key = \
00221 (GPrivate*) (value)), \
00222 (private_key, value))
00223 #define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
00224
00225 #define g_thread_create(func, data, joinable, error) \
00226 (g_thread_create_full (func, data, 0, joinable, FALSE, \
00227 G_THREAD_PRIORITY_NORMAL, error))
00228
00229 IMPORT_C GThread* g_thread_create_full (GThreadFunc func,
00230 gpointer data,
00231 gulong stack_size,
00232 gboolean joinable,
00233 gboolean bound,
00234 GThreadPriority priority,
00235 GError **error);
00236 IMPORT_C GThread* g_thread_self (void);
00237 IMPORT_C void g_thread_exit (gpointer retval);
00238 IMPORT_C gpointer g_thread_join (GThread *thread);
00239
00240 IMPORT_C void g_thread_set_priority (GThread *thread,
00241 GThreadPriority priority);
00242
00243
00244
00245
00246
00247
00248 #define g_static_mutex_lock(mutex) \
00249 g_mutex_lock (g_static_mutex_get_mutex (mutex))
00250 #define g_static_mutex_trylock(mutex) \
00251 g_mutex_trylock (g_static_mutex_get_mutex (mutex))
00252 #define g_static_mutex_unlock(mutex) \
00253 g_mutex_unlock (g_static_mutex_get_mutex (mutex))
00254 IMPORT_C void g_static_mutex_init (GStaticMutex *mutex);
00255 IMPORT_C void g_static_mutex_free (GStaticMutex *mutex);
00256
00257 struct _GStaticPrivate
00258 {
00259
00260 guint index;
00261 };
00262 #define G_STATIC_PRIVATE_INIT { 0 }
00263 IMPORT_C void g_static_private_init (GStaticPrivate *private_key);
00264 IMPORT_C gpointer g_static_private_get (GStaticPrivate *private_key);
00265 IMPORT_C void g_static_private_set (GStaticPrivate *private_key,
00266 gpointer data,
00267 GDestroyNotify notify);
00268 IMPORT_C void g_static_private_free (GStaticPrivate *private_key);
00269
00270 typedef struct _GStaticRecMutex GStaticRecMutex;
00271 struct _GStaticRecMutex
00272 {
00273
00274 GStaticMutex mutex;
00275 guint depth;
00276 GSystemThread owner;
00277 };
00278
00279 #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
00280 IMPORT_C void g_static_rec_mutex_init (GStaticRecMutex *mutex);
00281 IMPORT_C void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
00282 IMPORT_C gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
00283 IMPORT_C void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
00284 IMPORT_C void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
00285 guint depth);
00286 IMPORT_C guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
00287 IMPORT_C void g_static_rec_mutex_free (GStaticRecMutex *mutex);
00288
00289 typedef struct _GStaticRWLock GStaticRWLock;
00290 struct _GStaticRWLock
00291 {
00292
00293 GStaticMutex mutex;
00294 GCond *read_cond;
00295 GCond *write_cond;
00296 guint read_counter;
00297 gboolean have_writer;
00298 guint want_to_read;
00299 guint want_to_write;
00300 };
00301
00302 #define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }
00303
00304 IMPORT_C void g_static_rw_lock_init (GStaticRWLock* lock);
00305 IMPORT_C void g_static_rw_lock_reader_lock (GStaticRWLock* lock);
00306 IMPORT_C gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock);
00307 IMPORT_C void g_static_rw_lock_reader_unlock (GStaticRWLock* lock);
00308 IMPORT_C void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
00309 IMPORT_C gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
00310 IMPORT_C void g_static_rw_lock_writer_unlock (GStaticRWLock* lock);
00311 IMPORT_C void g_static_rw_lock_free (GStaticRWLock* lock);
00312
00313 IMPORT_C void g_thread_foreach (GFunc thread_func,
00314 gpointer user_data);
00315
00316 typedef enum
00317 {
00318 G_ONCE_STATUS_NOTCALLED,
00319 G_ONCE_STATUS_PROGRESS,
00320 G_ONCE_STATUS_READY
00321 } GOnceStatus;
00322
00323 typedef struct _GOnce GOnce;
00324 struct _GOnce
00325 {
00326 volatile GOnceStatus status;
00327 volatile gpointer retval;
00328 };
00329
00330 #define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
00331
00332 IMPORT_C gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg);
00333
00334 #ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
00335 # define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
00336 #else
00337 # define g_once(once, func, arg) \
00338 (((once)->status == G_ONCE_STATUS_READY) ? \
00339 (once)->retval : \
00340 g_once_impl ((once), (func), (arg)))
00341 #endif
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 #ifdef SYMBIAN
00353 #ifdef G_DEBUG_LOCKS
00354 #undef G_DEBUG_LOCKS
00355
00356 #endif
00357
00358 #endif
00359
00360 extern void glib_dummy_decl (void);
00361 #define G_LOCK_NAME(name) g__ ## name ## _lock
00362 #ifdef G_THREADS_ENABLED
00363 # define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
00364 # define G_LOCK_DEFINE(name) \
00365 GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
00366 # define G_LOCK_EXTERN(name) extern GStaticMutex G_LOCK_NAME (name)
00367
00368 # ifdef G_DEBUG_LOCKS
00369 # define G_LOCK(name) G_STMT_START{ \
00370 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00371 "file %s: line %d (%s): locking: %s ", \
00372 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00373 #name); \
00374 g_static_mutex_lock (&G_LOCK_NAME (name)); \
00375 }G_STMT_END
00376 # define G_UNLOCK(name) G_STMT_START{ \
00377 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00378 "file %s: line %d (%s): unlocking: %s ", \
00379 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00380 #name); \
00381 g_static_mutex_unlock (&G_LOCK_NAME (name)); \
00382 }G_STMT_END
00383 # define G_TRYLOCK(name) \
00384 (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00385 "file %s: line %d (%s): try locking: %s ", \
00386 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00387 #name), g_static_mutex_trylock (&G_LOCK_NAME (name)))
00388 # else
00389 # define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name))
00390 # define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name))
00391 # define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
00392 # endif
00393 #else
00394 # define G_LOCK_DEFINE_STATIC(name) extern void glib_dummy_decl (void)
00395 # define G_LOCK_DEFINE(name) extern void glib_dummy_decl (void)
00396 # define G_LOCK_EXTERN(name) extern void glib_dummy_decl (void)
00397 # define G_LOCK(name)
00398 # define G_UNLOCK(name)
00399 # define G_TRYLOCK(name) (TRUE)
00400 #endif
00401
00402
00403 G_END_DECLS
00404
00405 #endif
00406