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 #ifndef __G_THREAD_H__
00028 #define __G_THREAD_H__
00029
00030 #include <gerror.h>
00031
00032 G_BEGIN_DECLS
00033
00034 #ifndef GLIB_VAR
00035 # ifdef G_OS_WIN32
00036 # ifdef GLIB_COMPILATION
00037 # define GLIB_VAR __declspec(dllexport)
00038 # else
00039 # define GLIB_VAR extern __declspec(dllimport)
00040 # endif
00041 # else
00042 # define GLIB_VAR extern
00043 # endif
00044 #endif
00045
00046
00047
00048
00049 extern GQuark g_thread_error_quark();
00050 #define G_THREAD_ERROR g_thread_error_quark()
00051
00052 typedef enum
00053 {
00054 G_THREAD_ERROR_AGAIN
00055 } GThreadError;
00056
00057 typedef void (*GThreadFunc) (gpointer value);
00058
00059 typedef enum
00060 {
00061 G_THREAD_PRIORITY_LOW,
00062 G_THREAD_PRIORITY_NORMAL,
00063 G_THREAD_PRIORITY_HIGH,
00064 G_THREAD_PRIORITY_URGENT
00065 } GThreadPriority;
00066
00067 typedef struct _GThread GThread;
00068 struct _GThread
00069 {
00070 GThreadPriority priority;
00071 gboolean bound;
00072 gboolean joinable;
00073 };
00074
00075 typedef struct _GMutex GMutex;
00076 typedef struct _GCond GCond;
00077 typedef struct _GPrivate GPrivate;
00078 typedef struct _GStaticPrivate GStaticPrivate;
00079
00080 typedef struct _GThreadFunctions GThreadFunctions;
00081 struct _GThreadFunctions
00082 {
00083 GMutex* (*mutex_new) (void);
00084 void (*mutex_lock) (GMutex *mutex);
00085 gboolean (*mutex_trylock) (GMutex *mutex);
00086 void (*mutex_unlock) (GMutex *mutex);
00087 void (*mutex_free) (GMutex *mutex);
00088 GCond* (*cond_new) (void);
00089 void (*cond_signal) (GCond *cond);
00090 void (*cond_broadcast) (GCond *cond);
00091 void (*cond_wait) (GCond *cond,
00092 GMutex *mutex);
00093 gboolean (*cond_timed_wait) (GCond *cond,
00094 GMutex *mutex,
00095 GTimeVal *end_time);
00096 void (*cond_free) (GCond *cond);
00097 GPrivate* (*private_new) (GDestroyNotify destructor);
00098 gpointer (*private_get) (GPrivate *private_key);
00099 void (*private_set) (GPrivate *private_key,
00100 gpointer data);
00101 void (*thread_create) (GThreadFunc thread_func,
00102 gpointer arg,
00103 gulong stack_size,
00104 gboolean joinable,
00105 gboolean bound,
00106 GThreadPriority priority,
00107 gpointer thread,
00108 GError **error);
00109 void (*thread_yield) (void);
00110 void (*thread_join) (gpointer thread);
00111 void (*thread_exit) (void);
00112 void (*thread_set_priority)(gpointer thread,
00113 GThreadPriority priority);
00114 void (*thread_self) (gpointer thread);
00115 };
00116
00117 GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use;
00118 GLIB_VAR gboolean g_thread_use_default_impl;
00119 GLIB_VAR gboolean g_threads_got_initialized;
00120
00121
00122
00123
00124
00125 void g_thread_init (GThreadFunctions *vtable);
00126
00127
00128
00129
00130
00131
00132
00133
00134 void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
00135
00136
00137 #define G_MUTEX_DEBUG_MAGIC 0xf8e18ad7
00138
00139 #ifdef G_ERRORCHECK_MUTEXES
00140 #define g_thread_init(vtable) g_thread_init_with_errorcheck_mutexes (vtable)
00141 #endif
00142
00143
00144 GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
00145
00146
00147
00148 #define G_THREAD_UF(op, arglist) \
00149 (*g_thread_functions_for_glib_use . op) arglist
00150 #define G_THREAD_CF(op, fail, arg) \
00151 (g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
00152 #define G_THREAD_ECF(op, fail, mutex, type) \
00153 (g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
00154 (*g_thread_functions_for_glib_use . op)) \
00155 (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
00156
00157 #ifndef G_ERRORCHECK_MUTEXES
00158 # define g_mutex_lock(mutex) \
00159 G_THREAD_CF (mutex_lock, (void)0, (mutex))
00160 # define g_mutex_trylock(mutex) \
00161 G_THREAD_CF (mutex_trylock, TRUE, (mutex))
00162 # define g_mutex_unlock(mutex) \
00163 G_THREAD_CF (mutex_unlock, (void)0, (mutex))
00164 # define g_cond_wait(cond, mutex) \
00165 G_THREAD_CF (cond_wait, (void)0, (cond, mutex))
00166 # define g_cond_timed_wait(cond, mutex, abs_time) \
00167 G_THREAD_CF (cond_timed_wait, TRUE, (cond, mutex, abs_time))
00168 #else
00169 # define g_mutex_lock(mutex) \
00170 G_THREAD_ECF (mutex_lock, (void)0, mutex, void)
00171 # define g_mutex_trylock(mutex) \
00172 G_THREAD_ECF (mutex_trylock, TRUE, mutex, gboolean)
00173 # define g_mutex_unlock(mutex) \
00174 G_THREAD_ECF (mutex_unlock, (void)0, mutex, void)
00175 # define g_cond_wait(cond, mutex) \
00176 (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\
00177 g_thread_functions_for_glib_use.cond_wait) \
00178 (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0)
00179 # define g_cond_timed_wait(cond, mutex, abs_time) \
00180 (g_thread_supported () ? \
00181 ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*)) \
00182 g_thread_functions_for_glib_use.cond_timed_wait) \
00183 (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE)
00184 #endif
00185
00186 #define g_thread_supported() (g_threads_got_initialized)
00187 #define g_mutex_new() G_THREAD_UF (mutex_new, ())
00188 #define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
00189 #define g_cond_new() G_THREAD_UF (cond_new, ())
00190 #define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
00191 #define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
00192 #define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
00193 #define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
00194 #define g_private_get(private_key) G_THREAD_CF (private_get, \
00195 ((gpointer)private_key), \
00196 (private_key))
00197 #define g_private_set(private_key, value) G_THREAD_CF (private_set, \
00198 (void) (private_key = \
00199 (GPrivate*) (value)), \
00200 (private_key, value))
00201 #define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ())
00202 #define g_thread_exit() G_THREAD_CF (thread_exit, (void)0, ())
00203
00204 GThread* g_thread_create (GThreadFunc thread_func,
00205 gpointer arg,
00206 gulong stack_size,
00207 gboolean joinable,
00208 gboolean bound,
00209 GThreadPriority priority,
00210 GError **error);
00211 GThread* g_thread_self (void);
00212 void g_thread_join (GThread *thread);
00213 void g_thread_set_priority (GThread *thread,
00214 GThreadPriority priority);
00215
00216
00217
00218
00219
00220
00221 #define g_static_mutex_lock(mutex) \
00222 g_mutex_lock (g_static_mutex_get_mutex (mutex))
00223 #define g_static_mutex_trylock(mutex) \
00224 g_mutex_trylock (g_static_mutex_get_mutex (mutex))
00225 #define g_static_mutex_unlock(mutex) \
00226 g_mutex_unlock (g_static_mutex_get_mutex (mutex))
00227
00228 struct _GStaticPrivate
00229 {
00230 guint index;
00231 };
00232 #define G_STATIC_PRIVATE_INIT { 0 }
00233 gpointer g_static_private_get (GStaticPrivate *private_key);
00234 void g_static_private_set (GStaticPrivate *private_key,
00235 gpointer data,
00236 GDestroyNotify notify);
00237 gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
00238 GThread *thread);
00239 void g_static_private_set_for_thread (GStaticPrivate *private_key,
00240 GThread *thread,
00241 gpointer data,
00242 GDestroyNotify notify);
00243
00244 typedef struct _GStaticRecMutex GStaticRecMutex;
00245 struct _GStaticRecMutex
00246 {
00247 GStaticMutex mutex;
00248 unsigned int depth;
00249 GSystemThread owner;
00250 };
00251
00252 #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
00253 void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
00254 gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
00255 void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
00256 void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
00257 guint depth);
00258 guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
00259
00260 typedef struct _GStaticRWLock GStaticRWLock;
00261 struct _GStaticRWLock
00262 {
00263 GStaticMutex mutex;
00264 GCond *read_cond;
00265 GCond *write_cond;
00266 guint read_counter;
00267 gboolean write;
00268 guint want_to_write;
00269 };
00270
00271 #define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
00272
00273 void g_static_rw_lock_reader_lock (GStaticRWLock* lock);
00274 gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock);
00275 void g_static_rw_lock_reader_unlock (GStaticRWLock* lock);
00276 void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
00277 gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
00278 void g_static_rw_lock_writer_unlock (GStaticRWLock* lock);
00279 void g_static_rw_lock_free (GStaticRWLock* lock);
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 extern void glib_dummy_decl (void);
00291 #define G_LOCK_NAME(name) g__ ## name ## _lock
00292 #ifdef G_THREADS_ENABLED
00293 # define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
00294 # define G_LOCK_DEFINE(name) \
00295 GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
00296 # define G_LOCK_EXTERN(name) extern GStaticMutex G_LOCK_NAME (name)
00297
00298 # ifdef G_DEBUG_LOCKS
00299 # define G_LOCK(name) G_STMT_START{ \
00300 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00301 "file %s: line %d (%s): locking: %s ", \
00302 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00303 #name); \
00304 g_static_mutex_lock (&G_LOCK_NAME (name)); \
00305 }G_STMT_END
00306 # define G_UNLOCK(name) G_STMT_START{ \
00307 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00308 "file %s: line %d (%s): unlocking: %s ", \
00309 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00310 #name); \
00311 g_static_mutex_unlock (&G_LOCK_NAME (name)); \
00312 }G_STMT_END
00313 # define G_TRYLOCK(name) \
00314 (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
00315 "file %s: line %d (%s): try locking: %s ", \
00316 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
00317 #name), g_static_mutex_trylock (&G_LOCK_NAME (name)))
00318 # else
00319 # define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name))
00320 # define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name))
00321 # define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
00322 # endif
00323 #else
00324 # define G_LOCK_DEFINE_STATIC(name) extern void glib_dummy_decl (void)
00325 # define G_LOCK_DEFINE(name) extern void glib_dummy_decl (void)
00326 # define G_LOCK_EXTERN(name) extern void glib_dummy_decl (void)
00327 # define G_LOCK(name)
00328 # define G_UNLOCK(name)
00329 # define G_TRYLOCK(name) (TRUE)
00330 #endif
00331
00332 G_END_DECLS
00333
00334 #endif
00335