File indexing completed on 2026-05-06 08:41:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #ifndef __G_THREAD_H__
0028 #define __G_THREAD_H__
0029
0030 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
0031 #error "Only <glib.h> can be included directly."
0032 #endif
0033
0034 #include <glib/gatomic.h>
0035 #include <glib/gerror.h>
0036 #include <glib/gutils.h>
0037
0038 G_BEGIN_DECLS
0039
0040 #define G_THREAD_ERROR g_thread_error_quark ()
0041 GLIB_AVAILABLE_IN_ALL
0042 GQuark g_thread_error_quark (void);
0043
0044 typedef enum
0045 {
0046 G_THREAD_ERROR_AGAIN
0047 } GThreadError;
0048
0049 typedef gpointer (*GThreadFunc) (gpointer data);
0050
0051 typedef struct _GThread GThread;
0052
0053 typedef union _GMutex GMutex;
0054 typedef struct _GRecMutex GRecMutex;
0055 typedef struct _GRWLock GRWLock;
0056 typedef struct _GCond GCond;
0057 typedef struct _GPrivate GPrivate;
0058 typedef struct _GOnce GOnce;
0059
0060 union _GMutex
0061 {
0062
0063 gpointer p;
0064 guint i[2];
0065 };
0066
0067 struct _GRWLock
0068 {
0069
0070 gpointer p;
0071 guint i[2];
0072 };
0073
0074 struct _GCond
0075 {
0076
0077 gpointer p;
0078 guint i[2];
0079 };
0080
0081 struct _GRecMutex
0082 {
0083
0084 gpointer p;
0085 guint i[2];
0086 };
0087
0088 #define G_PRIVATE_INIT(notify) { NULL, (notify), { NULL, NULL } }
0089 struct _GPrivate
0090 {
0091
0092 gpointer p;
0093 GDestroyNotify notify;
0094 gpointer future[2];
0095 };
0096
0097 typedef enum
0098 {
0099 G_ONCE_STATUS_NOTCALLED,
0100 G_ONCE_STATUS_PROGRESS,
0101 G_ONCE_STATUS_READY
0102 } GOnceStatus;
0103
0104 #define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
0105 struct _GOnce
0106 {
0107 volatile GOnceStatus status;
0108 volatile gpointer retval;
0109 };
0110
0111 #define G_LOCK_NAME(name) g__ ## name ## _lock
0112 #define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
0113 #define G_LOCK_DEFINE(name) GMutex G_LOCK_NAME (name)
0114 #define G_LOCK_EXTERN(name) extern GMutex G_LOCK_NAME (name)
0115
0116 #ifdef G_DEBUG_LOCKS
0117 # define G_LOCK(name) G_STMT_START{ \
0118 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
0119 "file %s: line %d (%s): locking: %s ", \
0120 __FILE__, __LINE__, G_STRFUNC, \
0121 #name); \
0122 g_mutex_lock (&G_LOCK_NAME (name)); \
0123 }G_STMT_END
0124 # define G_UNLOCK(name) G_STMT_START{ \
0125 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
0126 "file %s: line %d (%s): unlocking: %s ", \
0127 __FILE__, __LINE__, G_STRFUNC, \
0128 #name); \
0129 g_mutex_unlock (&G_LOCK_NAME (name)); \
0130 }G_STMT_END
0131 # define G_TRYLOCK(name) \
0132 (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
0133 "file %s: line %d (%s): try locking: %s ", \
0134 __FILE__, __LINE__, G_STRFUNC, \
0135 #name), g_mutex_trylock (&G_LOCK_NAME (name)))
0136 #else
0137 # define G_LOCK(name) g_mutex_lock (&G_LOCK_NAME (name))
0138 # define G_UNLOCK(name) g_mutex_unlock (&G_LOCK_NAME (name))
0139 # define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name))
0140 #endif
0141
0142 #ifdef g_autoptr
0143 #define G_AUTO_LOCK(name) G_MUTEX_AUTO_LOCK (&G_LOCK_NAME (name), g__##name##_locker)
0144 #endif
0145
0146 GLIB_AVAILABLE_IN_2_32
0147 GThread * g_thread_ref (GThread *thread);
0148 GLIB_AVAILABLE_IN_2_32
0149 void g_thread_unref (GThread *thread);
0150 GLIB_AVAILABLE_IN_2_32
0151 GThread * g_thread_new (const gchar *name,
0152 GThreadFunc func,
0153 gpointer data);
0154 GLIB_AVAILABLE_IN_2_32
0155 GThread * g_thread_try_new (const gchar *name,
0156 GThreadFunc func,
0157 gpointer data,
0158 GError **error);
0159 GLIB_AVAILABLE_IN_ALL
0160 GThread * g_thread_self (void);
0161 G_NORETURN GLIB_AVAILABLE_IN_ALL
0162 void g_thread_exit (gpointer retval);
0163 GLIB_AVAILABLE_IN_ALL
0164 gpointer g_thread_join (GThread *thread);
0165 GLIB_AVAILABLE_IN_ALL
0166 void g_thread_yield (void);
0167
0168 GLIB_AVAILABLE_IN_2_84
0169 const char * g_thread_get_name (GThread *thread);
0170
0171 GLIB_AVAILABLE_IN_2_32
0172 void g_mutex_init (GMutex *mutex);
0173 GLIB_AVAILABLE_IN_2_32
0174 void g_mutex_clear (GMutex *mutex);
0175 GLIB_AVAILABLE_IN_ALL
0176 void g_mutex_lock (GMutex *mutex);
0177 GLIB_AVAILABLE_IN_ALL
0178 gboolean g_mutex_trylock (GMutex *mutex);
0179 GLIB_AVAILABLE_IN_ALL
0180 void g_mutex_unlock (GMutex *mutex);
0181
0182 GLIB_AVAILABLE_IN_2_32
0183 void g_rw_lock_init (GRWLock *rw_lock);
0184 GLIB_AVAILABLE_IN_2_32
0185 void g_rw_lock_clear (GRWLock *rw_lock);
0186 GLIB_AVAILABLE_IN_2_32
0187 void g_rw_lock_writer_lock (GRWLock *rw_lock);
0188 GLIB_AVAILABLE_IN_2_32
0189 gboolean g_rw_lock_writer_trylock (GRWLock *rw_lock);
0190 GLIB_AVAILABLE_IN_2_32
0191 void g_rw_lock_writer_unlock (GRWLock *rw_lock);
0192 GLIB_AVAILABLE_IN_2_32
0193 void g_rw_lock_reader_lock (GRWLock *rw_lock);
0194 GLIB_AVAILABLE_IN_2_32
0195 gboolean g_rw_lock_reader_trylock (GRWLock *rw_lock);
0196 GLIB_AVAILABLE_IN_2_32
0197 void g_rw_lock_reader_unlock (GRWLock *rw_lock);
0198
0199 GLIB_AVAILABLE_IN_2_32
0200 void g_rec_mutex_init (GRecMutex *rec_mutex);
0201 GLIB_AVAILABLE_IN_2_32
0202 void g_rec_mutex_clear (GRecMutex *rec_mutex);
0203 GLIB_AVAILABLE_IN_2_32
0204 void g_rec_mutex_lock (GRecMutex *rec_mutex);
0205 GLIB_AVAILABLE_IN_2_32
0206 gboolean g_rec_mutex_trylock (GRecMutex *rec_mutex);
0207 GLIB_AVAILABLE_IN_2_32
0208 void g_rec_mutex_unlock (GRecMutex *rec_mutex);
0209
0210 GLIB_AVAILABLE_IN_2_32
0211 void g_cond_init (GCond *cond);
0212 GLIB_AVAILABLE_IN_2_32
0213 void g_cond_clear (GCond *cond);
0214 GLIB_AVAILABLE_IN_ALL
0215 void g_cond_wait (GCond *cond,
0216 GMutex *mutex);
0217 GLIB_AVAILABLE_IN_ALL
0218 void g_cond_signal (GCond *cond);
0219 GLIB_AVAILABLE_IN_ALL
0220 void g_cond_broadcast (GCond *cond);
0221 GLIB_AVAILABLE_IN_2_32
0222 gboolean g_cond_wait_until (GCond *cond,
0223 GMutex *mutex,
0224 gint64 end_time);
0225
0226 GLIB_AVAILABLE_IN_ALL
0227 gpointer g_private_get (GPrivate *key);
0228 GLIB_AVAILABLE_IN_ALL
0229 void g_private_set (GPrivate *key,
0230 gpointer value);
0231 GLIB_AVAILABLE_IN_2_32
0232 void g_private_replace (GPrivate *key,
0233 gpointer value);
0234
0235 GLIB_AVAILABLE_IN_ALL
0236 gpointer g_once_impl (GOnce *once,
0237 GThreadFunc func,
0238 gpointer arg);
0239 GLIB_AVAILABLE_IN_ALL
0240 gboolean g_once_init_enter (volatile void *location);
0241 GLIB_AVAILABLE_IN_ALL
0242 void g_once_init_leave (volatile void *location,
0243 gsize result);
0244
0245 GLIB_AVAILABLE_IN_2_80
0246 gboolean g_once_init_enter_pointer (void *location);
0247 GLIB_AVAILABLE_IN_2_80
0248 void g_once_init_leave_pointer (void *location,
0249 gpointer result);
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 #if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && defined(__ATOMIC_SEQ_CST)
0261 # define g_once(once, func, arg) \
0262 ((__atomic_load_n (&(once)->status, __ATOMIC_ACQUIRE) == G_ONCE_STATUS_READY) ? \
0263 (once)->retval : \
0264 g_once_impl ((once), (func), (arg)))
0265 #else
0266 # define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
0267 #endif
0268
0269 #ifdef __GNUC__
0270 # define g_once_init_enter(location) \
0271 (G_GNUC_EXTENSION ({ \
0272 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
0273 (void) (0 ? (gpointer) *(location) : NULL); \
0274 (!g_atomic_pointer_get (location) && \
0275 g_once_init_enter (location)); \
0276 }))
0277 # define g_once_init_leave(location, result) \
0278 (G_GNUC_EXTENSION ({ \
0279 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
0280 0 ? (void) (*(location) = (result)) : (void) 0; \
0281 g_once_init_leave ((location), (gsize) (result)); \
0282 }))
0283 # define g_once_init_enter_pointer(location) \
0284 (G_GNUC_EXTENSION ({ \
0285 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
0286 (void) (0 ? (gpointer) * (location) : NULL); \
0287 (!g_atomic_pointer_get (location) && \
0288 g_once_init_enter_pointer (location)); \
0289 })) GLIB_AVAILABLE_MACRO_IN_2_80
0290 # define g_once_init_leave_pointer(location, result) \
0291 (G_GNUC_EXTENSION ({ \
0292 G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
0293 0 ? (void) (*(location) = (result)) : (void) 0; \
0294 g_once_init_leave_pointer ((location), (gpointer) (guintptr) (result)); \
0295 })) GLIB_AVAILABLE_MACRO_IN_2_80
0296 #else
0297 # define g_once_init_enter(location) \
0298 (g_once_init_enter((location)))
0299 # define g_once_init_leave(location, result) \
0300 (g_once_init_leave((location), (gsize) (result)))
0301 # define g_once_init_enter_pointer(location) \
0302 (g_once_init_enter_pointer((location))) \
0303 GLIB_AVAILABLE_MACRO_IN_2_80
0304 # define g_once_init_leave_pointer(location, result) \
0305 (g_once_init_leave_pointer((location), (gpointer) (guintptr) (result))) \
0306 GLIB_AVAILABLE_MACRO_IN_2_80
0307 #endif
0308
0309 GLIB_AVAILABLE_IN_2_36
0310 guint g_get_num_processors (void);
0311
0312
0313
0314
0315
0316
0317
0318 typedef void GMutexLocker;
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
0367 static inline GMutexLocker *
0368 g_mutex_locker_new (GMutex *mutex)
0369 {
0370 g_mutex_lock (mutex);
0371 return (GMutexLocker *) mutex;
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
0385 static inline void
0386 g_mutex_locker_free (GMutexLocker *locker)
0387 {
0388 g_mutex_unlock ((GMutex *) locker);
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428 #ifdef g_autoptr
0429 #define G_MUTEX_AUTO_LOCK(mutex, var) \
0430 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GMutexLocker) \
0431 G_GNUC_UNUSED var = g_mutex_locker_new (mutex)
0432 #endif
0433
0434
0435
0436
0437
0438
0439
0440 typedef void GRecMutexLocker;
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0489 GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
0490 static inline GRecMutexLocker *
0491 g_rec_mutex_locker_new (GRecMutex *rec_mutex)
0492 {
0493 g_rec_mutex_lock (rec_mutex);
0494 return (GRecMutexLocker *) rec_mutex;
0495 }
0496 G_GNUC_END_IGNORE_DEPRECATIONS
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0509 GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
0510 static inline void
0511 g_rec_mutex_locker_free (GRecMutexLocker *locker)
0512 {
0513 g_rec_mutex_unlock ((GRecMutex *) locker);
0514 }
0515 G_GNUC_END_IGNORE_DEPRECATIONS
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554 #ifdef g_autoptr
0555 #define G_REC_MUTEX_AUTO_LOCK(mutex, var) \
0556 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRecMutexLocker) \
0557 G_GNUC_UNUSED var = g_rec_mutex_locker_new (mutex)
0558 #endif
0559
0560
0561
0562
0563
0564
0565
0566 typedef void GRWLockWriterLocker;
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0646 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
0647 static inline GRWLockWriterLocker *
0648 g_rw_lock_writer_locker_new (GRWLock *rw_lock)
0649 {
0650 g_rw_lock_writer_lock (rw_lock);
0651 return (GRWLockWriterLocker *) rw_lock;
0652 }
0653 G_GNUC_END_IGNORE_DEPRECATIONS
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0667 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
0668 static inline void
0669 g_rw_lock_writer_locker_free (GRWLockWriterLocker *locker)
0670 {
0671 g_rw_lock_writer_unlock ((GRWLock *) locker);
0672 }
0673 G_GNUC_END_IGNORE_DEPRECATIONS
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712 #ifdef g_autoptr
0713 #define G_RW_LOCK_WRITER_AUTO_LOCK(mutex, var) \
0714 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockWriterLocker) \
0715 G_GNUC_UNUSED var = g_rw_lock_writer_locker_new (mutex)
0716 #endif
0717
0718
0719
0720
0721
0722
0723
0724 typedef void GRWLockReaderLocker;
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0744 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
0745 static inline GRWLockReaderLocker *
0746 g_rw_lock_reader_locker_new (GRWLock *rw_lock)
0747 {
0748 g_rw_lock_reader_lock (rw_lock);
0749 return (GRWLockReaderLocker *) rw_lock;
0750 }
0751 G_GNUC_END_IGNORE_DEPRECATIONS
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
0765 GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
0766 static inline void
0767 g_rw_lock_reader_locker_free (GRWLockReaderLocker *locker)
0768 {
0769 g_rw_lock_reader_unlock ((GRWLock *) locker);
0770 }
0771 G_GNUC_END_IGNORE_DEPRECATIONS
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810 #ifdef g_autoptr
0811 #define G_RW_LOCK_READER_AUTO_LOCK(mutex, var) \
0812 GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockReaderLocker) \
0813 G_GNUC_UNUSED var = g_rw_lock_reader_locker_new (mutex)
0814 #endif
0815
0816 G_END_DECLS
0817
0818 #endif