mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 03:02:10 +01:00
Merge branch 'auto-lock' into 'main'
Add G_*_AUTO_LOCK macros Closes #3223 See merge request GNOME/glib!3822
This commit is contained in:
commit
aee343fe5c
@ -142,6 +142,20 @@
|
|||||||
* %G_LOCK_DEFINE.
|
* %G_LOCK_DEFINE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_AUTO_LOCK:
|
||||||
|
* @name: the name of the lock
|
||||||
|
*
|
||||||
|
* Works like [func@GLib.MUTEX_AUTO_LOCK], but for a lock defined with
|
||||||
|
* [func@GLib.LOCK_DEFINE].
|
||||||
|
*
|
||||||
|
* This feature is only supported on GCC and clang. This macro is not defined on
|
||||||
|
* other compilers and should not be used in programs that are intended to be
|
||||||
|
* portable to those compilers.
|
||||||
|
*
|
||||||
|
* Since: 2.80
|
||||||
|
*/
|
||||||
|
|
||||||
/* GMutex Documentation {{{1 ------------------------------------------ */
|
/* GMutex Documentation {{{1 ------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
194
glib/gthread.h
194
glib/gthread.h
@ -139,6 +139,10 @@ struct _GOnce
|
|||||||
# define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name))
|
# define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name))
|
||||||
#endif /* !G_DEBUG_LOCKS */
|
#endif /* !G_DEBUG_LOCKS */
|
||||||
|
|
||||||
|
#ifdef g_autoptr
|
||||||
|
#define G_AUTO_LOCK(name) G_MUTEX_AUTO_LOCK (&G_LOCK_NAME (name), g__##name##_locker)
|
||||||
|
#endif /* g_autoptr */
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_2_32
|
GLIB_AVAILABLE_IN_2_32
|
||||||
GThread * g_thread_ref (GThread *thread);
|
GThread * g_thread_ref (GThread *thread);
|
||||||
GLIB_AVAILABLE_IN_2_32
|
GLIB_AVAILABLE_IN_2_32
|
||||||
@ -339,7 +343,7 @@ typedef void GMutexLocker;
|
|||||||
*
|
*
|
||||||
* // Code with mutex locked here
|
* // Code with mutex locked here
|
||||||
*
|
*
|
||||||
* if (cond)
|
* if (condition)
|
||||||
* // No need to unlock
|
* // No need to unlock
|
||||||
* return;
|
* return;
|
||||||
*
|
*
|
||||||
@ -350,6 +354,10 @@ typedef void GMutexLocker;
|
|||||||
* }
|
* }
|
||||||
* ]|
|
* ]|
|
||||||
*
|
*
|
||||||
|
* Note that it is common for the declared variable to not be used in the scope,
|
||||||
|
* which causes some compilers to warn. That can be avoided by using
|
||||||
|
* `G_GNUC_UNUSED` or, since 2.80, [func@GLib.MUTEX_AUTO_LOCK].
|
||||||
|
*
|
||||||
* Returns: a #GMutexLocker
|
* Returns: a #GMutexLocker
|
||||||
* Since: 2.44
|
* Since: 2.44
|
||||||
*/
|
*/
|
||||||
@ -378,6 +386,49 @@ g_mutex_locker_free (GMutexLocker *locker)
|
|||||||
g_mutex_unlock ((GMutex *) locker);
|
g_mutex_unlock ((GMutex *) locker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_MUTEX_AUTO_LOCK:
|
||||||
|
* @mutex: a [type@GLib.Mutex]
|
||||||
|
* @var: a variable name to be declared
|
||||||
|
*
|
||||||
|
* Declare a [type@GLib.MutexLocker] variable with `g_autoptr()` and lock the
|
||||||
|
* mutex. The mutex will be unlocked automatically when leaving the scope. The
|
||||||
|
* variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it is
|
||||||
|
* not used in the scope.
|
||||||
|
*
|
||||||
|
* This feature is only supported on GCC and clang. This macro is not defined on
|
||||||
|
* other compilers and should not be used in programs that are intended to be
|
||||||
|
* portable to those compilers.
|
||||||
|
*
|
||||||
|
* Note that this should be used in a place where it is allowed to declare a
|
||||||
|
* variable, which could be before any statement in the case
|
||||||
|
* `-Wdeclaration-after-statement` is used, or C standard prior to C99.
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* {
|
||||||
|
* G_MUTEX_AUTO_LOCK (&obj->mutex, locker);
|
||||||
|
*
|
||||||
|
* obj->stuff_with_lock ();
|
||||||
|
* if (condition)
|
||||||
|
* {
|
||||||
|
* // No need to unlock
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Unlock before end of scope
|
||||||
|
* g_clear_pointer (&locker, g_mutex_locker_free);
|
||||||
|
* obj->stuff_without_lock ();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 2.80.0
|
||||||
|
*/
|
||||||
|
#ifdef g_autoptr
|
||||||
|
#define G_MUTEX_AUTO_LOCK(mutex, var) \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GMutexLocker) \
|
||||||
|
G_GNUC_UNUSED var = g_mutex_locker_new (mutex)
|
||||||
|
#endif /* g_autoptr */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GRecMutexLocker:
|
* GRecMutexLocker:
|
||||||
*
|
*
|
||||||
@ -414,7 +465,7 @@ typedef void GRecMutexLocker;
|
|||||||
*
|
*
|
||||||
* // Code with rec_mutex locked here
|
* // Code with rec_mutex locked here
|
||||||
*
|
*
|
||||||
* if (cond)
|
* if (condition)
|
||||||
* // No need to unlock
|
* // No need to unlock
|
||||||
* return;
|
* return;
|
||||||
*
|
*
|
||||||
@ -425,6 +476,10 @@ typedef void GRecMutexLocker;
|
|||||||
* }
|
* }
|
||||||
* ]|
|
* ]|
|
||||||
*
|
*
|
||||||
|
* Note that it is common for the declared variable to not be used in the scope,
|
||||||
|
* which causes some compilers to warn. That can be avoided by using
|
||||||
|
* `G_GNUC_UNUSED` or, since 2.80, [func@GLib.REC_MUTEX_AUTO_LOCK].
|
||||||
|
*
|
||||||
* Returns: a #GRecMutexLocker
|
* Returns: a #GRecMutexLocker
|
||||||
* Since: 2.60
|
* Since: 2.60
|
||||||
*/
|
*/
|
||||||
@ -457,6 +512,49 @@ g_rec_mutex_locker_free (GRecMutexLocker *locker)
|
|||||||
}
|
}
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_REC_MUTEX_AUTO_LOCK:
|
||||||
|
* @mutex: a [type@GLib.RecMutex]
|
||||||
|
* @var: a variable name to be declared
|
||||||
|
*
|
||||||
|
* Declare a [type@GLib.RecMutexLocker] variable with `g_autoptr()` and lock the
|
||||||
|
* mutex. The mutex will be unlocked automatically when leaving the scope. The
|
||||||
|
* variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it is
|
||||||
|
* not used in the scope.
|
||||||
|
*
|
||||||
|
* This feature is only supported on GCC and clang. This macro is not defined on
|
||||||
|
* other compilers and should not be used in programs that are intended to be
|
||||||
|
* portable to those compilers.
|
||||||
|
*
|
||||||
|
* Note that this should be used in a place where it is allowed to declare a
|
||||||
|
* variable, which could be before any statement in the case
|
||||||
|
* `-Wdeclaration-after-statement` is used, or C standard prior to C99.
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* {
|
||||||
|
* G_REC_MUTEX_AUTO_LOCK (&obj->rec_mutex, locker);
|
||||||
|
*
|
||||||
|
* obj->stuff_with_lock ();
|
||||||
|
* if (condition)
|
||||||
|
* {
|
||||||
|
* // No need to unlock
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Unlock before end of scope
|
||||||
|
* g_clear_pointer (&locker, g_rec_mutex_locker_free);
|
||||||
|
* obj->stuff_without_lock ();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 2.80.0
|
||||||
|
*/
|
||||||
|
#ifdef g_autoptr
|
||||||
|
#define G_REC_MUTEX_AUTO_LOCK(mutex, var) \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRecMutexLocker) \
|
||||||
|
G_GNUC_UNUSED var = g_rec_mutex_locker_new (mutex)
|
||||||
|
#endif /* g_autoptr */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GRWLockWriterLocker:
|
* GRWLockWriterLocker:
|
||||||
*
|
*
|
||||||
@ -520,7 +618,7 @@ typedef void GRWLockWriterLocker;
|
|||||||
* if (self->array == NULL)
|
* if (self->array == NULL)
|
||||||
* self->array = g_ptr_array_new ();
|
* self->array = g_ptr_array_new ();
|
||||||
*
|
*
|
||||||
* if (cond)
|
* if (condition)
|
||||||
* // No need to unlock
|
* // No need to unlock
|
||||||
* return;
|
* return;
|
||||||
*
|
*
|
||||||
@ -535,6 +633,10 @@ typedef void GRWLockWriterLocker;
|
|||||||
* }
|
* }
|
||||||
* ]|
|
* ]|
|
||||||
*
|
*
|
||||||
|
* Note that it is common for the declared variable to not be used in the scope,
|
||||||
|
* which causes some compilers to warn. That can be avoided by using
|
||||||
|
* `G_GNUC_UNUSED` or, since 2.80, [func@GLib.RW_LOCK_WRITER_AUTO_LOCK].
|
||||||
|
*
|
||||||
* Returns: a #GRWLockWriterLocker
|
* Returns: a #GRWLockWriterLocker
|
||||||
* Since: 2.62
|
* Since: 2.62
|
||||||
*/
|
*/
|
||||||
@ -568,6 +670,49 @@ g_rw_lock_writer_locker_free (GRWLockWriterLocker *locker)
|
|||||||
}
|
}
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_RW_LOCK_WRITER_AUTO_LOCK:
|
||||||
|
* @mutex: a [type@GLib.RWLock]
|
||||||
|
* @var: a variable name to be declared
|
||||||
|
*
|
||||||
|
* Declare a [type@GLib.RWLockWriterLocker] variable with `g_autoptr()` and lock
|
||||||
|
* for writing. The mutex will be unlocked automatically when leaving the scope.
|
||||||
|
* The variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it
|
||||||
|
* is not used in the scope.
|
||||||
|
*
|
||||||
|
* This feature is only supported on GCC and clang. This macro is not defined on
|
||||||
|
* other compilers and should not be used in programs that are intended to be
|
||||||
|
* portable to those compilers.
|
||||||
|
*
|
||||||
|
* Note that this should be used in a place where it is allowed to declare a
|
||||||
|
* variable, which could be before any statement in the case
|
||||||
|
* `-Wdeclaration-after-statement` is used, or C standard prior to C99.
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* {
|
||||||
|
* G_RW_LOCK_WRITER_AUTO_LOCK (&obj->rw_lock, locker);
|
||||||
|
*
|
||||||
|
* obj->stuff_with_lock ();
|
||||||
|
* if (condition)
|
||||||
|
* {
|
||||||
|
* // No need to unlock
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Unlock before end of scope
|
||||||
|
* g_clear_pointer (&locker, g_rw_lock_writer_locker_free);
|
||||||
|
* obj->stuff_without_lock ();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 2.80.0
|
||||||
|
*/
|
||||||
|
#ifdef g_autoptr
|
||||||
|
#define G_RW_LOCK_WRITER_AUTO_LOCK(mutex, var) \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockWriterLocker) \
|
||||||
|
G_GNUC_UNUSED var = g_rw_lock_writer_locker_new (mutex)
|
||||||
|
#endif /* g_autoptr */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GRWLockReaderLocker:
|
* GRWLockReaderLocker:
|
||||||
*
|
*
|
||||||
@ -623,6 +768,49 @@ g_rw_lock_reader_locker_free (GRWLockReaderLocker *locker)
|
|||||||
}
|
}
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_RW_LOCK_READER_AUTO_LOCK:
|
||||||
|
* @mutex: a [type@GLib.RWLock]
|
||||||
|
* @var: a variable name to be declared
|
||||||
|
*
|
||||||
|
* Declare a [type@GLib.RWLockReaderLocker] variable with `g_autoptr()` and lock
|
||||||
|
* for reading. The mutex will be unlocked automatically when leaving the scope.
|
||||||
|
* The variable is declared with `G_GNUC_UNUSED` to avoid compiler warning if it
|
||||||
|
* is not used in the scope.
|
||||||
|
*
|
||||||
|
* This feature is only supported on GCC and clang. This macro is not defined on
|
||||||
|
* other compilers and should not be used in programs that are intended to be
|
||||||
|
* portable to those compilers.
|
||||||
|
*
|
||||||
|
* Note that this should be used in a place where it is allowed to declare a
|
||||||
|
* variable, which could be before any statement in the case
|
||||||
|
* `-Wdeclaration-after-statement` is used, or C standard prior to C99.
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* {
|
||||||
|
* G_RW_LOCK_READER_AUTO_LOCK (&obj->rw_lock, locker);
|
||||||
|
*
|
||||||
|
* obj->stuff_with_lock ();
|
||||||
|
* if (condition)
|
||||||
|
* {
|
||||||
|
* // No need to unlock
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Unlock before end of scope
|
||||||
|
* g_clear_pointer (&locker, g_rw_lock_reader_locker_free);
|
||||||
|
* obj->stuff_without_lock ();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 2.80.0
|
||||||
|
*/
|
||||||
|
#ifdef g_autoptr
|
||||||
|
#define G_RW_LOCK_READER_AUTO_LOCK(mutex, var) \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_80 g_autoptr (GRWLockReaderLocker) \
|
||||||
|
G_GNUC_UNUSED var = g_rw_lock_reader_locker_new (mutex)
|
||||||
|
#endif /* g_autoptr */
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_THREAD_H__ */
|
#endif /* __G_THREAD_H__ */
|
||||||
|
@ -399,6 +399,12 @@ test_g_mutex_locker (void)
|
|||||||
|
|
||||||
g_mutex_init (&mutex);
|
g_mutex_init (&mutex);
|
||||||
|
|
||||||
|
if (TRUE)
|
||||||
|
{
|
||||||
|
/* val is unused in this scope but compiler should not warn. */
|
||||||
|
G_MUTEX_AUTO_LOCK (&mutex, val);
|
||||||
|
}
|
||||||
|
|
||||||
if (TRUE)
|
if (TRUE)
|
||||||
{
|
{
|
||||||
g_autoptr(GMutexLocker) val = g_mutex_locker_new (&mutex);
|
g_autoptr(GMutexLocker) val = g_mutex_locker_new (&mutex);
|
||||||
@ -442,6 +448,12 @@ test_g_rec_mutex_locker (void)
|
|||||||
|
|
||||||
g_rec_mutex_init (&rec_mutex);
|
g_rec_mutex_init (&rec_mutex);
|
||||||
|
|
||||||
|
if (TRUE)
|
||||||
|
{
|
||||||
|
/* val is unused in this scope but compiler should not warn. */
|
||||||
|
G_REC_MUTEX_AUTO_LOCK (&rec_mutex, val);
|
||||||
|
}
|
||||||
|
|
||||||
if (TRUE)
|
if (TRUE)
|
||||||
{
|
{
|
||||||
g_autoptr(GRecMutexLocker) val = g_rec_mutex_locker_new (&rec_mutex);
|
g_autoptr(GRecMutexLocker) val = g_rec_mutex_locker_new (&rec_mutex);
|
||||||
@ -492,6 +504,18 @@ test_g_rw_lock_lockers (void)
|
|||||||
|
|
||||||
g_rw_lock_init (&lock);
|
g_rw_lock_init (&lock);
|
||||||
|
|
||||||
|
if (TRUE)
|
||||||
|
{
|
||||||
|
/* val is unused in this scope but compiler should not warn. */
|
||||||
|
G_RW_LOCK_WRITER_AUTO_LOCK (&lock, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TRUE)
|
||||||
|
{
|
||||||
|
/* val is unused in this scope but compiler should not warn. */
|
||||||
|
G_RW_LOCK_READER_AUTO_LOCK (&lock, val);
|
||||||
|
}
|
||||||
|
|
||||||
if (TRUE)
|
if (TRUE)
|
||||||
{
|
{
|
||||||
g_autoptr(GRWLockWriterLocker) val = g_rw_lock_writer_locker_new (&lock);
|
g_autoptr(GRWLockWriterLocker) val = g_rw_lock_writer_locker_new (&lock);
|
||||||
@ -533,6 +557,27 @@ test_g_rw_lock_lockers (void)
|
|||||||
g_rw_lock_clear (&lock);
|
g_rw_lock_clear (&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_LOCK_DEFINE (test_g_auto_lock);
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_g_auto_lock (void)
|
||||||
|
{
|
||||||
|
GThread *thread;
|
||||||
|
|
||||||
|
if (TRUE)
|
||||||
|
{
|
||||||
|
G_AUTO_LOCK (test_g_auto_lock);
|
||||||
|
|
||||||
|
/* Verify that the mutex is actually locked */
|
||||||
|
thread = g_thread_new ("mutex locked", mutex_locked_thread, &G_LOCK_NAME (test_g_auto_lock));
|
||||||
|
g_thread_join (thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that the mutex is unlocked again */
|
||||||
|
thread = g_thread_new ("mutex unlocked", mutex_unlocked_thread, &G_LOCK_NAME (test_g_auto_lock));
|
||||||
|
g_thread_join (thread);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_g_cond (void)
|
test_g_cond (void)
|
||||||
{
|
{
|
||||||
@ -785,6 +830,7 @@ main (int argc, gchar *argv[])
|
|||||||
g_test_add_func ("/autoptr/g_mutex_locker", test_g_mutex_locker);
|
g_test_add_func ("/autoptr/g_mutex_locker", test_g_mutex_locker);
|
||||||
g_test_add_func ("/autoptr/g_rec_mutex_locker", test_g_rec_mutex_locker);
|
g_test_add_func ("/autoptr/g_rec_mutex_locker", test_g_rec_mutex_locker);
|
||||||
g_test_add_func ("/autoptr/g_rw_lock_lockers", test_g_rw_lock_lockers);
|
g_test_add_func ("/autoptr/g_rw_lock_lockers", test_g_rw_lock_lockers);
|
||||||
|
g_test_add_func ("/autoptr/g_auto_lock", test_g_auto_lock);
|
||||||
g_test_add_func ("/autoptr/g_cond", test_g_cond);
|
g_test_add_func ("/autoptr/g_cond", test_g_cond);
|
||||||
g_test_add_func ("/autoptr/g_timer", test_g_timer);
|
g_test_add_func ("/autoptr/g_timer", test_g_timer);
|
||||||
g_test_add_func ("/autoptr/g_time_zone", test_g_time_zone);
|
g_test_add_func ("/autoptr/g_time_zone", test_g_time_zone);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user