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
38G_BEGIN_DECLS
39
40#define G_THREAD_ERROR g_thread_error_quark ()
41GLIB_AVAILABLE_IN_ALL
42GQuark g_thread_error_quark (void);
43
44typedef enum
45{
46 G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
47} GThreadError;
48
49typedef gpointer (*GThreadFunc) (gpointer data);
50
51typedef struct _GThread GThread;
52
53typedef union _GMutex GMutex;
54typedef struct _GRecMutex GRecMutex;
55typedef struct _GRWLock GRWLock;
56typedef struct _GCond GCond;
57typedef struct _GPrivate GPrivate;
58typedef struct _GOnce GOnce;
59
60union _GMutex
61{
62 /*< private >*/
63 gpointer p;
64 guint i[2];
65};
66
67struct _GRWLock
68{
69 /*< private >*/
70 gpointer p;
71 guint i[2];
72};
73
74struct _GCond
75{
76 /*< private >*/
77 gpointer p;
78 guint i[2];
79};
80
81struct _GRecMutex
82{
83 /*< private >*/
84 gpointer p;
85 guint i[2];
86};
87
88#define G_PRIVATE_INIT(notify) { NULL, (notify), { NULL, NULL } }
89struct _GPrivate
90{
91 /*< private >*/
92 gpointer p;
93 GDestroyNotify notify;
94 gpointer future[2];
95};
96
97typedef 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 }
105struct _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#ifdef g_autoptr
143#define G_AUTO_LOCK(name) G_MUTEX_AUTO_LOCK (&G_LOCK_NAME (name), g__##name##_locker)
144#endif /* g_autoptr */
145
146GLIB_AVAILABLE_IN_2_32
147GThread * g_thread_ref (GThread *thread);
148GLIB_AVAILABLE_IN_2_32
149void g_thread_unref (GThread *thread);
150GLIB_AVAILABLE_IN_2_32
151GThread * g_thread_new (const gchar *name,
152 GThreadFunc func,
153 gpointer data);
154GLIB_AVAILABLE_IN_2_32
155GThread * g_thread_try_new (const gchar *name,
156 GThreadFunc func,
157 gpointer data,
158 GError **error);
159GLIB_AVAILABLE_IN_ALL
160GThread * g_thread_self (void);
161G_NORETURN GLIB_AVAILABLE_IN_ALL
162void g_thread_exit (gpointer retval);
163GLIB_AVAILABLE_IN_ALL
164gpointer g_thread_join (GThread *thread);
165GLIB_AVAILABLE_IN_ALL
166void g_thread_yield (void);
167
168GLIB_AVAILABLE_IN_2_84
169const char * g_thread_get_name (GThread *thread);
170
171GLIB_AVAILABLE_IN_2_32
172void g_mutex_init (GMutex *mutex);
173GLIB_AVAILABLE_IN_2_32
174void g_mutex_clear (GMutex *mutex);
175GLIB_AVAILABLE_IN_ALL
176void g_mutex_lock (GMutex *mutex);
177GLIB_AVAILABLE_IN_ALL
178gboolean g_mutex_trylock (GMutex *mutex);
179GLIB_AVAILABLE_IN_ALL
180void g_mutex_unlock (GMutex *mutex);
181
182GLIB_AVAILABLE_IN_2_32
183void g_rw_lock_init (GRWLock *rw_lock);
184GLIB_AVAILABLE_IN_2_32
185void g_rw_lock_clear (GRWLock *rw_lock);
186GLIB_AVAILABLE_IN_2_32
187void g_rw_lock_writer_lock (GRWLock *rw_lock);
188GLIB_AVAILABLE_IN_2_32
189gboolean g_rw_lock_writer_trylock (GRWLock *rw_lock);
190GLIB_AVAILABLE_IN_2_32
191void g_rw_lock_writer_unlock (GRWLock *rw_lock);
192GLIB_AVAILABLE_IN_2_32
193void g_rw_lock_reader_lock (GRWLock *rw_lock);
194GLIB_AVAILABLE_IN_2_32
195gboolean g_rw_lock_reader_trylock (GRWLock *rw_lock);
196GLIB_AVAILABLE_IN_2_32
197void g_rw_lock_reader_unlock (GRWLock *rw_lock);
198
199GLIB_AVAILABLE_IN_2_32
200void g_rec_mutex_init (GRecMutex *rec_mutex);
201GLIB_AVAILABLE_IN_2_32
202void g_rec_mutex_clear (GRecMutex *rec_mutex);
203GLIB_AVAILABLE_IN_2_32
204void g_rec_mutex_lock (GRecMutex *rec_mutex);
205GLIB_AVAILABLE_IN_2_32
206gboolean g_rec_mutex_trylock (GRecMutex *rec_mutex);
207GLIB_AVAILABLE_IN_2_32
208void g_rec_mutex_unlock (GRecMutex *rec_mutex);
209
210GLIB_AVAILABLE_IN_2_32
211void g_cond_init (GCond *cond);
212GLIB_AVAILABLE_IN_2_32
213void g_cond_clear (GCond *cond);
214GLIB_AVAILABLE_IN_ALL
215void g_cond_wait (GCond *cond,
216 GMutex *mutex);
217GLIB_AVAILABLE_IN_ALL
218void g_cond_signal (GCond *cond);
219GLIB_AVAILABLE_IN_ALL
220void g_cond_broadcast (GCond *cond);
221GLIB_AVAILABLE_IN_2_32
222gboolean g_cond_wait_until (GCond *cond,
223 GMutex *mutex,
224 gint64 end_time);
225
226GLIB_AVAILABLE_IN_ALL
227gpointer g_private_get (GPrivate *key);
228GLIB_AVAILABLE_IN_ALL
229void g_private_set (GPrivate *key,
230 gpointer value);
231GLIB_AVAILABLE_IN_2_32
232void g_private_replace (GPrivate *key,
233 gpointer value);
234
235GLIB_AVAILABLE_IN_ALL
236gpointer g_once_impl (GOnce *once,
237 GThreadFunc func,
238 gpointer arg);
239GLIB_AVAILABLE_IN_ALL
240gboolean g_once_init_enter (volatile void *location);
241GLIB_AVAILABLE_IN_ALL
242void g_once_init_leave (volatile void *location,
243 gsize result);
244
245GLIB_AVAILABLE_IN_2_80
246gboolean g_once_init_enter_pointer (void *location);
247GLIB_AVAILABLE_IN_2_80
248void g_once_init_leave_pointer (void *location,
249 gpointer result);
250
251/* Use C11-style atomic extensions to check the fast path for status=ready. If
252 * they are not available, fall back to using a mutex and condition variable in
253 * g_once_impl().
254 *
255 * On the C11-style codepath, only the load of once->status needs to be atomic,
256 * as the writes to it and once->retval in g_once_impl() are related by a
257 * happens-before relation. Release-acquire semantics are defined such that any
258 * atomic/non-atomic write which happens-before a store/release is guaranteed to
259 * be seen by the load/acquire of the same atomic variable. */
260#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && defined(__ATOMIC_SEQ_CST)
261# define g_once(once, func, arg) \
262 ((__atomic_load_n (&(once)->status, __ATOMIC_ACQUIRE) == G_ONCE_STATUS_READY) ? \
263 (once)->retval : \
264 g_once_impl ((once), (func), (arg)))
265#else
266# define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
267#endif
268
269#ifdef __GNUC__
270# define g_once_init_enter(location) \
271 (G_GNUC_EXTENSION ({ \
272 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
273 (void) (0 ? (gpointer) *(location) : NULL); \
274 (!g_atomic_pointer_get (location) && \
275 g_once_init_enter (location)); \
276 }))
277# define g_once_init_leave(location, result) \
278 (G_GNUC_EXTENSION ({ \
279 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
280 0 ? (void) (*(location) = (result)) : (void) 0; \
281 g_once_init_leave ((location), (gsize) (result)); \
282 }))
283# define g_once_init_enter_pointer(location) \
284 (G_GNUC_EXTENSION ({ \
285 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
286 (void) (0 ? (gpointer) * (location) : NULL); \
287 (!g_atomic_pointer_get (location) && \
288 g_once_init_enter_pointer (location)); \
289 })) GLIB_AVAILABLE_MACRO_IN_2_80
290# define g_once_init_leave_pointer(location, result) \
291 (G_GNUC_EXTENSION ({ \
292 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
293 0 ? (void) (*(location) = (result)) : (void) 0; \
294 g_once_init_leave_pointer ((location), (gpointer) (guintptr) (result)); \
295 })) GLIB_AVAILABLE_MACRO_IN_2_80
296#else
297# define g_once_init_enter(location) \
298 (g_once_init_enter((location)))
299# define g_once_init_leave(location, result) \
300 (g_once_init_leave((location), (gsize) (result)))
301# define g_once_init_enter_pointer(location) \
302 (g_once_init_enter_pointer((location))) \
303 GLIB_AVAILABLE_MACRO_IN_2_80
304# define g_once_init_leave_pointer(location, result) \
305 (g_once_init_leave_pointer((location), (gpointer) (guintptr) (result))) \
306 GLIB_AVAILABLE_MACRO_IN_2_80
307#endif
308
309GLIB_AVAILABLE_IN_2_36
310guint g_get_num_processors (void);
311
312/**
313 * GMutexLocker:
314 *
315 * Opaque type. See g_mutex_locker_new() for details.
316 * Since: 2.44
317 */
318typedef void GMutexLocker;
319
320/**
321 * g_mutex_locker_new:
322 * @mutex: a mutex to lock
323 *
324 * Lock @mutex and return a new #GMutexLocker. Unlock with
325 * g_mutex_locker_free(). Using g_mutex_unlock() on @mutex
326 * while a #GMutexLocker exists can lead to undefined behaviour.
327 *
328 * No allocation is performed, it is equivalent to a g_mutex_lock() call.
329 *
330 * This is intended to be used with g_autoptr(). Note that g_autoptr()
331 * is only available when using GCC or clang, so the following example
332 * will only work with those compilers:
333 * |[
334 * typedef struct
335 * {
336 * ...
337 * GMutex mutex;
338 * ...
339 * } MyObject;
340 *
341 * static void
342 * my_object_do_stuff (MyObject *self)
343 * {
344 * g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->mutex);
345 *
346 * // Code with mutex locked here
347 *
348 * if (condition)
349 * // No need to unlock
350 * return;
351 *
352 * // Optionally early unlock
353 * g_clear_pointer (&locker, g_mutex_locker_free);
354 *
355 * // Code with mutex unlocked here
356 * }
357 * ]|
358 *
359 * Note that it is common for the declared variable to not be used in the scope,
360 * which causes some compilers to warn. That can be avoided by using
361 * `G_GNUC_UNUSED` or, since 2.80, [func@GLib.MUTEX_AUTO_LOCK].
362 *
363 * Returns: a #GMutexLocker
364 * Since: 2.44
365 */
366GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
367static inline GMutexLocker *
368g_mutex_locker_new (GMutex *mutex)
369{
370 g_mutex_lock (mutex);
371 return (GMutexLocker *) mutex;
372}
373
374/**
375 * g_mutex_locker_free:
376 * @locker: a GMutexLocker
377 *
378 * Unlock @locker's mutex. See g_mutex_locker_new() for details.
379 *
380 * No memory is freed, it is equivalent to a g_mutex_unlock() call.
381 *
382 * Since: 2.44
383 */
384GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
385static inline void
386g_mutex_locker_free (GMutexLocker *locker)
387{
388 g_mutex_unlock (mutex: (GMutex *) locker);
389}
390
391/**
392 * G_MUTEX_AUTO_LOCK:
393 * @mutex: a [type@GLib.Mutex]
394 * @var: a variable name to be declared
395 *
396 * Declare a [type@GLib.MutexLocker] variable with `g_autoptr()` and lock the
397 * mutex. The mutex will be unlocked automatically when leaving the scope. The
398 * variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it is
399 * not used in the scope.
400 *
401 * This feature is only supported on GCC and clang. This macro is not defined on
402 * other compilers and should not be used in programs that are intended to be
403 * portable to those compilers.
404 *
405 * Note that this should be used in a place where it is allowed to declare a
406 * variable, which could be before any statement in the case
407 * `-Wdeclaration-after-statement` is used, or C standard prior to C99.
408 *
409 * ```c
410 * {
411 * G_MUTEX_AUTO_LOCK (&obj->mutex, locker);
412 *
413 * obj->stuff_with_lock ();
414 * if (condition)
415 * {
416 * // No need to unlock
417 * return;
418 * }
419 *
420 * // Unlock before end of scope
421 * g_clear_pointer (&locker, g_mutex_locker_free);
422 * obj->stuff_without_lock ();
423 * }
424 * ```
425 *
426 * Since: 2.80.0
427 */
428#ifdef g_autoptr
429#define G_MUTEX_AUTO_LOCK(mutex, var) \
430 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GMutexLocker) \
431 G_GNUC_UNUSED var = g_mutex_locker_new (mutex)
432#endif /* g_autoptr */
433
434/**
435 * GRecMutexLocker:
436 *
437 * Opaque type. See g_rec_mutex_locker_new() for details.
438 * Since: 2.60
439 */
440typedef void GRecMutexLocker;
441
442/**
443 * g_rec_mutex_locker_new:
444 * @rec_mutex: a recursive mutex to lock
445 *
446 * Lock @rec_mutex and return a new #GRecMutexLocker. Unlock with
447 * g_rec_mutex_locker_free(). Using g_rec_mutex_unlock() on @rec_mutex
448 * while a #GRecMutexLocker exists can lead to undefined behaviour.
449 *
450 * No allocation is performed, it is equivalent to a g_rec_mutex_lock() call.
451 *
452 * This is intended to be used with g_autoptr(). Note that g_autoptr()
453 * is only available when using GCC or clang, so the following example
454 * will only work with those compilers:
455 * |[
456 * typedef struct
457 * {
458 * ...
459 * GRecMutex rec_mutex;
460 * ...
461 * } MyObject;
462 *
463 * static void
464 * my_object_do_stuff (MyObject *self)
465 * {
466 * g_autoptr(GRecMutexLocker) locker = g_rec_mutex_locker_new (&self->rec_mutex);
467 *
468 * // Code with rec_mutex locked here
469 *
470 * if (condition)
471 * // No need to unlock
472 * return;
473 *
474 * // Optionally early unlock
475 * g_clear_pointer (&locker, g_rec_mutex_locker_free);
476 *
477 * // Code with rec_mutex unlocked here
478 * }
479 * ]|
480 *
481 * Note that it is common for the declared variable to not be used in the scope,
482 * which causes some compilers to warn. That can be avoided by using
483 * `G_GNUC_UNUSED` or, since 2.80, [func@GLib.REC_MUTEX_AUTO_LOCK].
484 *
485 * Returns: a #GRecMutexLocker
486 * Since: 2.60
487 */
488G_GNUC_BEGIN_IGNORE_DEPRECATIONS
489GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
490static inline GRecMutexLocker *
491g_rec_mutex_locker_new (GRecMutex *rec_mutex)
492{
493 g_rec_mutex_lock (rec_mutex);
494 return (GRecMutexLocker *) rec_mutex;
495}
496G_GNUC_END_IGNORE_DEPRECATIONS
497
498/**
499 * g_rec_mutex_locker_free:
500 * @locker: a GRecMutexLocker
501 *
502 * Unlock @locker's recursive mutex. See g_rec_mutex_locker_new() for details.
503 *
504 * No memory is freed, it is equivalent to a g_rec_mutex_unlock() call.
505 *
506 * Since: 2.60
507 */
508G_GNUC_BEGIN_IGNORE_DEPRECATIONS
509GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
510static inline void
511g_rec_mutex_locker_free (GRecMutexLocker *locker)
512{
513 g_rec_mutex_unlock (rec_mutex: (GRecMutex *) locker);
514}
515G_GNUC_END_IGNORE_DEPRECATIONS
516
517/**
518 * G_REC_MUTEX_AUTO_LOCK:
519 * @mutex: a [type@GLib.RecMutex]
520 * @var: a variable name to be declared
521 *
522 * Declare a [type@GLib.RecMutexLocker] variable with `g_autoptr()` and lock the
523 * mutex. The mutex will be unlocked automatically when leaving the scope. The
524 * variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it is
525 * not used in the scope.
526 *
527 * This feature is only supported on GCC and clang. This macro is not defined on
528 * other compilers and should not be used in programs that are intended to be
529 * portable to those compilers.
530 *
531 * Note that this should be used in a place where it is allowed to declare a
532 * variable, which could be before any statement in the case
533 * `-Wdeclaration-after-statement` is used, or C standard prior to C99.
534 *
535 * ```c
536 * {
537 * G_REC_MUTEX_AUTO_LOCK (&obj->rec_mutex, locker);
538 *
539 * obj->stuff_with_lock ();
540 * if (condition)
541 * {
542 * // No need to unlock
543 * return;
544 * }
545 *
546 * // Unlock before end of scope
547 * g_clear_pointer (&locker, g_rec_mutex_locker_free);
548 * obj->stuff_without_lock ();
549 * }
550 * ```
551 *
552 * Since: 2.80.0
553 */
554#ifdef g_autoptr
555#define G_REC_MUTEX_AUTO_LOCK(mutex, var) \
556 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRecMutexLocker) \
557 G_GNUC_UNUSED var = g_rec_mutex_locker_new (mutex)
558#endif /* g_autoptr */
559
560/**
561 * GRWLockWriterLocker:
562 *
563 * Opaque type. See g_rw_lock_writer_locker_new() for details.
564 * Since: 2.62
565 */
566typedef void GRWLockWriterLocker;
567
568/**
569 * g_rw_lock_writer_locker_new:
570 * @rw_lock: a #GRWLock
571 *
572 * Obtain a write lock on @rw_lock and return a new #GRWLockWriterLocker.
573 * Unlock with g_rw_lock_writer_locker_free(). Using g_rw_lock_writer_unlock()
574 * on @rw_lock while a #GRWLockWriterLocker exists can lead to undefined
575 * behaviour.
576 *
577 * No allocation is performed, it is equivalent to a g_rw_lock_writer_lock() call.
578 *
579 * This is intended to be used with g_autoptr(). Note that g_autoptr()
580 * is only available when using GCC or clang, so the following example
581 * will only work with those compilers:
582 * |[
583 * typedef struct
584 * {
585 * ...
586 * GRWLock rw_lock;
587 * GPtrArray *array;
588 * ...
589 * } MyObject;
590 *
591 * static gchar *
592 * my_object_get_data (MyObject *self, guint index)
593 * {
594 * g_autoptr(GRWLockReaderLocker) locker = g_rw_lock_reader_locker_new (&self->rw_lock);
595 *
596 * // Code with a read lock obtained on rw_lock here
597 *
598 * if (self->array == NULL)
599 * // No need to unlock
600 * return NULL;
601 *
602 * if (index < self->array->len)
603 * // No need to unlock
604 * return g_ptr_array_index (self->array, index);
605 *
606 * // Optionally early unlock
607 * g_clear_pointer (&locker, g_rw_lock_reader_locker_free);
608 *
609 * // Code with rw_lock unlocked here
610 * return NULL;
611 * }
612 *
613 * static void
614 * my_object_set_data (MyObject *self, guint index, gpointer data)
615 * {
616 * g_autoptr(GRWLockWriterLocker) locker = g_rw_lock_writer_locker_new (&self->rw_lock);
617 *
618 * // Code with a write lock obtained on rw_lock here
619 *
620 * if (self->array == NULL)
621 * self->array = g_ptr_array_new ();
622 *
623 * if (condition)
624 * // No need to unlock
625 * return;
626 *
627 * if (index >= self->array->len)
628 * g_ptr_array_set_size (self->array, index+1);
629 * g_ptr_array_index (self->array, index) = data;
630 *
631 * // Optionally early unlock
632 * g_clear_pointer (&locker, g_rw_lock_writer_locker_free);
633 *
634 * // Code with rw_lock unlocked here
635 * }
636 * ]|
637 *
638 * Note that it is common for the declared variable to not be used in the scope,
639 * which causes some compilers to warn. That can be avoided by using
640 * `G_GNUC_UNUSED` or, since 2.80, [func@GLib.RW_LOCK_WRITER_AUTO_LOCK].
641 *
642 * Returns: a #GRWLockWriterLocker
643 * Since: 2.62
644 */
645G_GNUC_BEGIN_IGNORE_DEPRECATIONS
646GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
647static inline GRWLockWriterLocker *
648g_rw_lock_writer_locker_new (GRWLock *rw_lock)
649{
650 g_rw_lock_writer_lock (rw_lock);
651 return (GRWLockWriterLocker *) rw_lock;
652}
653G_GNUC_END_IGNORE_DEPRECATIONS
654
655/**
656 * g_rw_lock_writer_locker_free:
657 * @locker: a GRWLockWriterLocker
658 *
659 * Release a write lock on @locker's read-write lock. See
660 * g_rw_lock_writer_locker_new() for details.
661 *
662 * No memory is freed, it is equivalent to a g_rw_lock_writer_unlock() call.
663 *
664 * Since: 2.62
665 */
666G_GNUC_BEGIN_IGNORE_DEPRECATIONS
667GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
668static inline void
669g_rw_lock_writer_locker_free (GRWLockWriterLocker *locker)
670{
671 g_rw_lock_writer_unlock (rw_lock: (GRWLock *) locker);
672}
673G_GNUC_END_IGNORE_DEPRECATIONS
674
675/**
676 * G_RW_LOCK_WRITER_AUTO_LOCK:
677 * @mutex: a [type@GLib.RWLock]
678 * @var: a variable name to be declared
679 *
680 * Declare a [type@GLib.RWLockWriterLocker] variable with `g_autoptr()` and lock
681 * for writing. The mutex will be unlocked automatically when leaving the scope.
682 * The variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it
683 * is not used in the scope.
684 *
685 * This feature is only supported on GCC and clang. This macro is not defined on
686 * other compilers and should not be used in programs that are intended to be
687 * portable to those compilers.
688 *
689 * Note that this should be used in a place where it is allowed to declare a
690 * variable, which could be before any statement in the case
691 * `-Wdeclaration-after-statement` is used, or C standard prior to C99.
692 *
693 * ```c
694 * {
695 * G_RW_LOCK_WRITER_AUTO_LOCK (&obj->rw_lock, locker);
696 *
697 * obj->stuff_with_lock ();
698 * if (condition)
699 * {
700 * // No need to unlock
701 * return;
702 * }
703 *
704 * // Unlock before end of scope
705 * g_clear_pointer (&locker, g_rw_lock_writer_locker_free);
706 * obj->stuff_without_lock ();
707 * }
708 * ```
709 *
710 * Since: 2.80.0
711 */
712#ifdef g_autoptr
713#define G_RW_LOCK_WRITER_AUTO_LOCK(mutex, var) \
714 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockWriterLocker) \
715 G_GNUC_UNUSED var = g_rw_lock_writer_locker_new (mutex)
716#endif /* g_autoptr */
717
718/**
719 * GRWLockReaderLocker:
720 *
721 * Opaque type. See g_rw_lock_reader_locker_new() for details.
722 * Since: 2.62
723 */
724typedef void GRWLockReaderLocker;
725
726/**
727 * g_rw_lock_reader_locker_new:
728 * @rw_lock: a #GRWLock
729 *
730 * Obtain a read lock on @rw_lock and return a new #GRWLockReaderLocker.
731 * Unlock with g_rw_lock_reader_locker_free(). Using g_rw_lock_reader_unlock()
732 * on @rw_lock while a #GRWLockReaderLocker exists can lead to undefined
733 * behaviour.
734 *
735 * No allocation is performed, it is equivalent to a g_rw_lock_reader_lock() call.
736 *
737 * This is intended to be used with g_autoptr(). For a code sample, see
738 * g_rw_lock_writer_locker_new().
739 *
740 * Returns: a #GRWLockReaderLocker
741 * Since: 2.62
742 */
743G_GNUC_BEGIN_IGNORE_DEPRECATIONS
744GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
745static inline GRWLockReaderLocker *
746g_rw_lock_reader_locker_new (GRWLock *rw_lock)
747{
748 g_rw_lock_reader_lock (rw_lock);
749 return (GRWLockReaderLocker *) rw_lock;
750}
751G_GNUC_END_IGNORE_DEPRECATIONS
752
753/**
754 * g_rw_lock_reader_locker_free:
755 * @locker: a GRWLockReaderLocker
756 *
757 * Release a read lock on @locker's read-write lock. See
758 * g_rw_lock_reader_locker_new() for details.
759 *
760 * No memory is freed, it is equivalent to a g_rw_lock_reader_unlock() call.
761 *
762 * Since: 2.62
763 */
764G_GNUC_BEGIN_IGNORE_DEPRECATIONS
765GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
766static inline void
767g_rw_lock_reader_locker_free (GRWLockReaderLocker *locker)
768{
769 g_rw_lock_reader_unlock (rw_lock: (GRWLock *) locker);
770}
771G_GNUC_END_IGNORE_DEPRECATIONS
772
773/**
774 * G_RW_LOCK_READER_AUTO_LOCK:
775 * @mutex: a [type@GLib.RWLock]
776 * @var: a variable name to be declared
777 *
778 * Declare a [type@GLib.RWLockReaderLocker] variable with `g_autoptr()` and lock
779 * for reading. The mutex will be unlocked automatically when leaving the scope.
780 * The variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it
781 * is not used in the scope.
782 *
783 * This feature is only supported on GCC and clang. This macro is not defined on
784 * other compilers and should not be used in programs that are intended to be
785 * portable to those compilers.
786 *
787 * Note that this should be used in a place where it is allowed to declare a
788 * variable, which could be before any statement in the case
789 * `-Wdeclaration-after-statement` is used, or C standard prior to C99.
790 *
791 * ```c
792 * {
793 * G_RW_LOCK_READER_AUTO_LOCK (&obj->rw_lock, locker);
794 *
795 * obj->stuff_with_lock ();
796 * if (condition)
797 * {
798 * // No need to unlock
799 * return;
800 * }
801 *
802 * // Unlock before end of scope
803 * g_clear_pointer (&locker, g_rw_lock_reader_locker_free);
804 * obj->stuff_without_lock ();
805 * }
806 * ```
807 *
808 * Since: 2.80.0
809 */
810#ifdef g_autoptr
811#define G_RW_LOCK_READER_AUTO_LOCK(mutex, var) \
812 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockReaderLocker) \
813 G_GNUC_UNUSED var = g_rw_lock_reader_locker_new (mutex)
814#endif /* g_autoptr */
815
816G_END_DECLS
817
818#endif /* __G_THREAD_H__ */
819