gthread.h 26 KB

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