1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27 #ifndef __G_THREAD_H__
28 #define __G_THREAD_H__
29
30 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
31 #error "Only <glib.h> can be included directly."
32 #endif
33
34 #include <glib/gatomic.h>
35 #include <glib/gerror.h>
36 #include <glib/gutils.h>
37
38 G_BEGIN_DECLS
39
40 #define G_THREAD_ERROR g_thread_error_quark ()
41 GLIB_AVAILABLE_IN_ALL
42 GQuark g_thread_error_quark (void);
43
44 typedef enum
45 {
46 G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
47 } GThreadError;
48
49 typedef gpointer (*GThreadFunc) (gpointer data);
50
51 typedef struct _GThread GThread;
52
53 typedef union _GMutex GMutex;
54 typedef struct _GRecMutex GRecMutex;
55 typedef struct _GRWLock GRWLock;
56 typedef struct _GCond GCond;
57 typedef struct _GPrivate GPrivate;
58 typedef struct _GOnce GOnce;
59
60 union _GMutex
61 {
62 /*< private >*/
63 gpointer p;
64 guint i[2];
65 };
66
67 struct _GRWLock
68 {
69 /*< private >*/
70 gpointer p;
71 guint i[2];
72 };
73
74 struct _GCond
75 {
76 /*< private >*/
77 gpointer p;
78 guint i[2];
79 };
80
81 struct _GRecMutex
82 {
83 /*< private >*/
84 gpointer p;
85 guint i[2];
86 };
87
88 #define G_PRIVATE_INIT(notify) { NULL, (notify), { NULL, NULL } }
89 struct _GPrivate
90 {
91 /*< private >*/
92 gpointer p;
93 GDestroyNotify notify;
94 gpointer future[2];
95 };
96
97 typedef enum
98 {
99 G_ONCE_STATUS_NOTCALLED,
100 G_ONCE_STATUS_PROGRESS,
101 G_ONCE_STATUS_READY
102 } GOnceStatus;
103
104 #define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
105 struct _GOnce
106 {
107 volatile GOnceStatus status;
108 volatile gpointer retval;
109 };
110
111 #define G_LOCK_NAME(name) g__ ## name ## _lock
112 #define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
113 #define G_LOCK_DEFINE(name) GMutex G_LOCK_NAME (name)
114 #define G_LOCK_EXTERN(name) extern GMutex G_LOCK_NAME (name)
115
116 #ifdef G_DEBUG_LOCKS
117 # define G_LOCK(name) G_STMT_START{ \
118 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
119 "file %s: line %d (%s): locking: %s ", \
120 __FILE__, __LINE__, G_STRFUNC, \
121 #name); \
122 g_mutex_lock (&G_LOCK_NAME (name)); \
123 }G_STMT_END
124 # define G_UNLOCK(name) G_STMT_START{ \
125 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
126 "file %s: line %d (%s): unlocking: %s ", \
127 __FILE__, __LINE__, G_STRFUNC, \
128 #name); \
129 g_mutex_unlock (&G_LOCK_NAME (name)); \
130 }G_STMT_END
131 # define G_TRYLOCK(name) \
132 (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
133 "file %s: line %d (%s): try locking: %s ", \
134 __FILE__, __LINE__, G_STRFUNC, \
135 #name), g_mutex_trylock (&G_LOCK_NAME (name)))
136 #else /* !G_DEBUG_LOCKS */
137 # define G_LOCK(name) g_mutex_lock (&G_LOCK_NAME (name))
138 # define G_UNLOCK(name) g_mutex_unlock (&G_LOCK_NAME (name))
139 # define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name))
140 #endif /* !G_DEBUG_LOCKS */
141
142 GLIB_AVAILABLE_IN_2_32
143 GThread * g_thread_ref (GThread *thread);
144 GLIB_AVAILABLE_IN_2_32
145 void g_thread_unref (GThread *thread);
146 GLIB_AVAILABLE_IN_2_32
147 GThread * g_thread_new (const gchar *name,
148 GThreadFunc func,
149 gpointer data);
150 GLIB_AVAILABLE_IN_2_32
151 GThread * g_thread_try_new (const gchar *name,
152 GThreadFunc func,
153 gpointer data,
154 GError **error);
155 GLIB_AVAILABLE_IN_ALL
156 GThread * g_thread_self (void);
157 G_NORETURN GLIB_AVAILABLE_IN_ALL
158 void g_thread_exit (gpointer retval);
159 GLIB_AVAILABLE_IN_ALL
160 gpointer g_thread_join (GThread *thread);
161 GLIB_AVAILABLE_IN_ALL
162 void g_thread_yield (void);
163
164
165 GLIB_AVAILABLE_IN_2_32
166 void g_mutex_init (GMutex *mutex);
167 GLIB_AVAILABLE_IN_2_32
168 void g_mutex_clear (GMutex *mutex);
169 GLIB_AVAILABLE_IN_ALL
170 void g_mutex_lock (GMutex *mutex);
171 GLIB_AVAILABLE_IN_ALL
172 gboolean g_mutex_trylock (GMutex *mutex);
173 GLIB_AVAILABLE_IN_ALL
174 void g_mutex_unlock (GMutex *mutex);
175
176 GLIB_AVAILABLE_IN_2_32
177 void g_rw_lock_init (GRWLock *rw_lock);
178 GLIB_AVAILABLE_IN_2_32
179 void g_rw_lock_clear (GRWLock *rw_lock);
180 GLIB_AVAILABLE_IN_2_32
181 void g_rw_lock_writer_lock (GRWLock *rw_lock);
182 GLIB_AVAILABLE_IN_2_32
183 gboolean g_rw_lock_writer_trylock (GRWLock *rw_lock);
184 GLIB_AVAILABLE_IN_2_32
185 void g_rw_lock_writer_unlock (GRWLock *rw_lock);
186 GLIB_AVAILABLE_IN_2_32
187 void g_rw_lock_reader_lock (GRWLock *rw_lock);
188 GLIB_AVAILABLE_IN_2_32
189 gboolean g_rw_lock_reader_trylock (GRWLock *rw_lock);
190 GLIB_AVAILABLE_IN_2_32
191 void g_rw_lock_reader_unlock (GRWLock *rw_lock);
192
193 GLIB_AVAILABLE_IN_2_32
194 void g_rec_mutex_init (GRecMutex *rec_mutex);
195 GLIB_AVAILABLE_IN_2_32
196 void g_rec_mutex_clear (GRecMutex *rec_mutex);
197 GLIB_AVAILABLE_IN_2_32
198 void g_rec_mutex_lock (GRecMutex *rec_mutex);
199 GLIB_AVAILABLE_IN_2_32
200 gboolean g_rec_mutex_trylock (GRecMutex *rec_mutex);
201 GLIB_AVAILABLE_IN_2_32
202 void g_rec_mutex_unlock (GRecMutex *rec_mutex);
203
204 GLIB_AVAILABLE_IN_2_32
205 void g_cond_init (GCond *cond);
206 GLIB_AVAILABLE_IN_2_32
207 void g_cond_clear (GCond *cond);
208 GLIB_AVAILABLE_IN_ALL
209 void g_cond_wait (GCond *cond,
210 GMutex *mutex);
211 GLIB_AVAILABLE_IN_ALL
212 void g_cond_signal (GCond *cond);
213 GLIB_AVAILABLE_IN_ALL
214 void g_cond_broadcast (GCond *cond);
215 GLIB_AVAILABLE_IN_2_32
216 gboolean g_cond_wait_until (GCond *cond,
217 GMutex *mutex,
218 gint64 end_time);
219
220 GLIB_AVAILABLE_IN_ALL
221 gpointer g_private_get (GPrivate *key);
222 GLIB_AVAILABLE_IN_ALL
223 void g_private_set (GPrivate *key,
224 gpointer value);
225 GLIB_AVAILABLE_IN_2_32
226 void g_private_replace (GPrivate *key,
227 gpointer value);
228
229 GLIB_AVAILABLE_IN_ALL
230 gpointer g_once_impl (GOnce *once,
231 GThreadFunc func,
232 gpointer arg);
233 GLIB_AVAILABLE_IN_ALL
234 gboolean g_once_init_enter (volatile void *location);
235 GLIB_AVAILABLE_IN_ALL
236 void g_once_init_leave (volatile void *location,
237 gsize result);
238
239 GLIB_AVAILABLE_IN_2_80
240 gboolean g_once_init_enter_pointer (void *location);
241 GLIB_AVAILABLE_IN_2_80
242 void g_once_init_leave_pointer (void *location,
243 gpointer result);
244
245 /* Use C11-style atomic extensions to check the fast path for status=ready. If
246 * they are not available, fall back to using a mutex and condition variable in
247 * g_once_impl().
248 *
249 * On the C11-style codepath, only the load of once->status needs to be atomic,
250 * as the writes to it and once->retval in g_once_impl() are related by a
251 * happens-before relation. Release-acquire semantics are defined such that any
252 * atomic/non-atomic write which happens-before a store/release is guaranteed to
253 * be seen by the load/acquire of the same atomic variable. */
254 #if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && defined(__ATOMIC_SEQ_CST)
255 # define g_once(once, func, arg) \
256 ((__atomic_load_n (&(once)->status, __ATOMIC_ACQUIRE) == G_ONCE_STATUS_READY) ? \
257 (once)->retval : \
258 g_once_impl ((once), (func), (arg)))
259 #else
260 # define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
261 #endif
262
263 #ifdef __GNUC__
264 # define g_once_init_enter(location) \
265 (G_GNUC_EXTENSION ({ \
266 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
267 (void) (0 ? (gpointer) *(location) : NULL); \
268 (!g_atomic_pointer_get (location) && \
269 g_once_init_enter (location)); \
270 }))
271 # define g_once_init_leave(location, result) \
272 (G_GNUC_EXTENSION ({ \
273 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
274 0 ? (void) (*(location) = (result)) : (void) 0; \
275 g_once_init_leave ((location), (gsize) (result)); \
276 }))
277 # define g_once_init_enter_pointer(location) \
278 (G_GNUC_EXTENSION ({ \
279 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
280 (void) (0 ? (gpointer) * (location) : NULL); \
281 (!g_atomic_pointer_get (location) && \
282 g_once_init_enter_pointer (location)); \
283 })) GLIB_AVAILABLE_MACRO_IN_2_80
284 # define g_once_init_leave_pointer(location, result) \
285 (G_GNUC_EXTENSION ({ \
286 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
287 0 ? (void) (*(location) = (result)) : (void) 0; \
288 g_once_init_leave_pointer ((location), (gpointer) (guintptr) (result)); \
289 })) GLIB_AVAILABLE_MACRO_IN_2_80
290 #else
291 # define g_once_init_enter(location) \
292 (g_once_init_enter((location)))
293 # define g_once_init_leave(location, result) \
294 (g_once_init_leave((location), (gsize) (result)))
295 # define g_once_init_enter_pointer(location) \
296 (g_once_init_enter_pointer((location))) \
297 GLIB_AVAILABLE_MACRO_IN_2_80
298 # define g_once_init_leave_pointer(location, result) \
299 (g_once_init_leave_pointer((location), (gpointer) (guintptr) (result))) \
300 GLIB_AVAILABLE_MACRO_IN_2_80
301 #endif
302
303 GLIB_AVAILABLE_IN_2_36
304 guint g_get_num_processors (void);
305
306 /**
307 * GMutexLocker:
308 *
309 * Opaque type. See g_mutex_locker_new() for details.
310 * Since: 2.44
311 */
312 typedef void GMutexLocker;
313
314 /**
315 * g_mutex_locker_new:
316 * @mutex: a mutex to lock
317 *
318 * Lock @mutex and return a new #GMutexLocker. Unlock with
319 * g_mutex_locker_free(). Using g_mutex_unlock() on @mutex
320 * while a #GMutexLocker exists can lead to undefined behaviour.
321 *
322 * No allocation is performed, it is equivalent to a g_mutex_lock() call.
323 *
324 * This is intended to be used with g_autoptr(). Note that g_autoptr()
325 * is only available when using GCC or clang, so the following example
326 * will only work with those compilers:
327 * |[
328 * typedef struct
329 * {
330 * ...
331 * GMutex mutex;
332 * ...
333 * } MyObject;
334 *
335 * static void
336 * my_object_do_stuff (MyObject *self)
337 * {
338 * g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->mutex);
339 *
340 * // Code with mutex locked here
341 *
342 * if (cond)
343 * // No need to unlock
344 * return;
345 *
346 * // Optionally early unlock
347 * g_clear_pointer (&locker, g_mutex_locker_free);
348 *
349 * // Code with mutex unlocked here
350 * }
351 * ]|
352 *
353 * Returns: a #GMutexLocker
354 * Since: 2.44
355 */
356 GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
357 static inline GMutexLocker *
358 g_mutex_locker_new (GMutex *mutex)
359 {
360 g_mutex_lock (mutex);
361 return (GMutexLocker *) mutex;
362 }
363
364 /**
365 * g_mutex_locker_free:
366 * @locker: a GMutexLocker
367 *
368 * Unlock @locker's mutex. See g_mutex_locker_new() for details.
369 *
370 * No memory is freed, it is equivalent to a g_mutex_unlock() call.
371 *
372 * Since: 2.44
373 */
374 GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
375 static inline void
376 g_mutex_locker_free (GMutexLocker *locker)
377 {
378 g_mutex_unlock ((GMutex *) locker);
379 }
380
381 /**
382 * GRecMutexLocker:
383 *
384 * Opaque type. See g_rec_mutex_locker_new() for details.
385 * Since: 2.60
386 */
387 typedef void GRecMutexLocker;
388
389 /**
390 * g_rec_mutex_locker_new:
391 * @rec_mutex: a recursive mutex to lock
392 *
393 * Lock @rec_mutex and return a new #GRecMutexLocker. Unlock with
394 * g_rec_mutex_locker_free(). Using g_rec_mutex_unlock() on @rec_mutex
395 * while a #GRecMutexLocker exists can lead to undefined behaviour.
396 *
397 * No allocation is performed, it is equivalent to a g_rec_mutex_lock() call.
398 *
399 * This is intended to be used with g_autoptr(). Note that g_autoptr()
400 * is only available when using GCC or clang, so the following example
401 * will only work with those compilers:
402 * |[
403 * typedef struct
404 * {
405 * ...
406 * GRecMutex rec_mutex;
407 * ...
408 * } MyObject;
409 *
410 * static void
411 * my_object_do_stuff (MyObject *self)
412 * {
413 * g_autoptr(GRecMutexLocker) locker = g_rec_mutex_locker_new (&self->rec_mutex);
414 *
415 * // Code with rec_mutex locked here
416 *
417 * if (cond)
418 * // No need to unlock
419 * return;
420 *
421 * // Optionally early unlock
422 * g_clear_pointer (&locker, g_rec_mutex_locker_free);
423 *
424 * // Code with rec_mutex unlocked here
425 * }
426 * ]|
427 *
428 * Returns: a #GRecMutexLocker
429 * Since: 2.60
430 */
431 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
432 GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
433 static inline GRecMutexLocker *
434 g_rec_mutex_locker_new (GRecMutex *rec_mutex)
435 {
436 g_rec_mutex_lock (rec_mutex);
437 return (GRecMutexLocker *) rec_mutex;
438 }
439 G_GNUC_END_IGNORE_DEPRECATIONS
440
441 /**
442 * g_rec_mutex_locker_free:
443 * @locker: a GRecMutexLocker
444 *
445 * Unlock @locker's recursive mutex. See g_rec_mutex_locker_new() for details.
446 *
447 * No memory is freed, it is equivalent to a g_rec_mutex_unlock() call.
448 *
449 * Since: 2.60
450 */
451 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
452 GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
453 static inline void
454 g_rec_mutex_locker_free (GRecMutexLocker *locker)
455 {
456 g_rec_mutex_unlock ((GRecMutex *) locker);
457 }
458 G_GNUC_END_IGNORE_DEPRECATIONS
459
460 /**
461 * GRWLockWriterLocker:
462 *
463 * Opaque type. See g_rw_lock_writer_locker_new() for details.
464 * Since: 2.62
465 */
466 typedef void GRWLockWriterLocker;
467
468 /**
469 * g_rw_lock_writer_locker_new:
470 * @rw_lock: a #GRWLock
471 *
472 * Obtain a write lock on @rw_lock and return a new #GRWLockWriterLocker.
473 * Unlock with g_rw_lock_writer_locker_free(). Using g_rw_lock_writer_unlock()
474 * on @rw_lock while a #GRWLockWriterLocker exists can lead to undefined
475 * behaviour.
476 *
477 * No allocation is performed, it is equivalent to a g_rw_lock_writer_lock() call.
478 *
479 * This is intended to be used with g_autoptr(). Note that g_autoptr()
480 * is only available when using GCC or clang, so the following example
481 * will only work with those compilers:
482 * |[
483 * typedef struct
484 * {
485 * ...
486 * GRWLock rw_lock;
487 * GPtrArray *array;
488 * ...
489 * } MyObject;
490 *
491 * static gchar *
492 * my_object_get_data (MyObject *self, guint index)
493 * {
494 * g_autoptr(GRWLockReaderLocker) locker = g_rw_lock_reader_locker_new (&self->rw_lock);
495 *
496 * // Code with a read lock obtained on rw_lock here
497 *
498 * if (self->array == NULL)
499 * // No need to unlock
500 * return NULL;
501 *
502 * if (index < self->array->len)
503 * // No need to unlock
504 * return g_ptr_array_index (self->array, index);
505 *
506 * // Optionally early unlock
507 * g_clear_pointer (&locker, g_rw_lock_reader_locker_free);
508 *
509 * // Code with rw_lock unlocked here
510 * return NULL;
511 * }
512 *
513 * static void
514 * my_object_set_data (MyObject *self, guint index, gpointer data)
515 * {
516 * g_autoptr(GRWLockWriterLocker) locker = g_rw_lock_writer_locker_new (&self->rw_lock);
517 *
518 * // Code with a write lock obtained on rw_lock here
519 *
520 * if (self->array == NULL)
521 * self->array = g_ptr_array_new ();
522 *
523 * if (cond)
524 * // No need to unlock
525 * return;
526 *
527 * if (index >= self->array->len)
528 * g_ptr_array_set_size (self->array, index+1);
529 * g_ptr_array_index (self->array, index) = data;
530 *
531 * // Optionally early unlock
532 * g_clear_pointer (&locker, g_rw_lock_writer_locker_free);
533 *
534 * // Code with rw_lock unlocked here
535 * }
536 * ]|
537 *
538 * Returns: a #GRWLockWriterLocker
539 * Since: 2.62
540 */
541 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
542 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
543 static inline GRWLockWriterLocker *
544 g_rw_lock_writer_locker_new (GRWLock *rw_lock)
545 {
546 g_rw_lock_writer_lock (rw_lock);
547 return (GRWLockWriterLocker *) rw_lock;
548 }
549 G_GNUC_END_IGNORE_DEPRECATIONS
550
551 /**
552 * g_rw_lock_writer_locker_free:
553 * @locker: a GRWLockWriterLocker
554 *
555 * Release a write lock on @locker's read-write lock. See
556 * g_rw_lock_writer_locker_new() for details.
557 *
558 * No memory is freed, it is equivalent to a g_rw_lock_writer_unlock() call.
559 *
560 * Since: 2.62
561 */
562 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
563 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
564 static inline void
565 g_rw_lock_writer_locker_free (GRWLockWriterLocker *locker)
566 {
567 g_rw_lock_writer_unlock ((GRWLock *) locker);
568 }
569 G_GNUC_END_IGNORE_DEPRECATIONS
570
571 /**
572 * GRWLockReaderLocker:
573 *
574 * Opaque type. See g_rw_lock_reader_locker_new() for details.
575 * Since: 2.62
576 */
577 typedef void GRWLockReaderLocker;
578
579 /**
580 * g_rw_lock_reader_locker_new:
581 * @rw_lock: a #GRWLock
582 *
583 * Obtain a read lock on @rw_lock and return a new #GRWLockReaderLocker.
584 * Unlock with g_rw_lock_reader_locker_free(). Using g_rw_lock_reader_unlock()
585 * on @rw_lock while a #GRWLockReaderLocker exists can lead to undefined
586 * behaviour.
587 *
588 * No allocation is performed, it is equivalent to a g_rw_lock_reader_lock() call.
589 *
590 * This is intended to be used with g_autoptr(). For a code sample, see
591 * g_rw_lock_writer_locker_new().
592 *
593 * Returns: a #GRWLockReaderLocker
594 * Since: 2.62
595 */
596 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
597 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
598 static inline GRWLockReaderLocker *
599 g_rw_lock_reader_locker_new (GRWLock *rw_lock)
600 {
601 g_rw_lock_reader_lock (rw_lock);
602 return (GRWLockReaderLocker *) rw_lock;
603 }
604 G_GNUC_END_IGNORE_DEPRECATIONS
605
606 /**
607 * g_rw_lock_reader_locker_free:
608 * @locker: a GRWLockReaderLocker
609 *
610 * Release a read lock on @locker's read-write lock. See
611 * g_rw_lock_reader_locker_new() for details.
612 *
613 * No memory is freed, it is equivalent to a g_rw_lock_reader_unlock() call.
614 *
615 * Since: 2.62
616 */
617 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
618 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
619 static inline void
620 g_rw_lock_reader_locker_free (GRWLockReaderLocker *locker)
621 {
622 g_rw_lock_reader_unlock ((GRWLock *) locker);
623 }
624 G_GNUC_END_IGNORE_DEPRECATIONS
625
626 G_END_DECLS
627
628 #endif /* __G_THREAD_H__ */