From 1404d3e12819b342fda74d082dcb067a029141b1 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Thu, 5 Feb 2015 10:35:42 -0500 Subject: [PATCH] Add GMutexLocker https://bugzilla.gnome.org/show_bug.cgi?id=744012 --- docs/reference/glib/glib-sections.txt | 5 ++ glib/glib-autocleanups.h | 1 + glib/gthread.h | 69 +++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index f48c2f00b..45827d6da 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -648,6 +648,11 @@ g_mutex_lock g_mutex_trylock g_mutex_unlock + +GMutexLocker +g_mutex_locker_new +g_mutex_locker_free + G_LOCK_DEFINE G_LOCK_DEFINE_STATIC diff --git a/glib/glib-autocleanups.h b/glib/glib-autocleanups.h index 4d9f7ee30..a3c059a0d 100644 --- a/glib/glib-autocleanups.h +++ b/glib/glib-autocleanups.h @@ -54,6 +54,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSList, g_slist_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GStringChunk, g_string_chunk_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GThread, g_thread_unref) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GMutex, g_mutex_clear) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMutexLocker, g_mutex_locker_free) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GCond, g_cond_clear) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTimer, g_timer_destroy) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTimeZone, g_time_zone_unref) diff --git a/glib/gthread.h b/glib/gthread.h index 3f026f631..d7b1f5884 100644 --- a/glib/gthread.h +++ b/glib/gthread.h @@ -266,6 +266,75 @@ void g_once_init_leave (volatile void *location, GLIB_AVAILABLE_IN_2_36 guint g_get_num_processors (void); +/** + * GMutexLocker: + * + * Opaque type. See g_mutex_locker_new() for details. + * Since: 2.44 + */ +typedef void GMutexLocker; + +/** + * g_mutex_locker_new: + * @mutex: a mutex to lock + * + * Lock @mutex and return a new #GMutexLocker. Unlock with + * g_mutex_locker_free(). Using g_mutex_unlock() on @mutex + * while a #GMutexLocker exists can lead to undefined behaviour. + * + * This is intended to be used with g_autoptr(). Note that g_autoptr() + * is only available when using GCC or clang, so the following example + * will only work with those compilers: + * |[ + * typedef struct + * { + * ... + * GMutex mutex; + * ... + * } MyObject; + * + * static void + * my_object_do_stuff (MyObject *self) + * { + * g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->mutex); + * + * // Code with mutex locked here + * + * if (cond) + * // No need to unlock + * return; + * + * // Optionally early unlock + * g_clear_pointer (&locker, g_mutex_locker_free); + * + * // Code with mutex unlocked here + * } + * ]| + * + * Returns: a #GMutexLocker + * Since: 2.44 + */ +static inline GMutexLocker * +g_mutex_locker_new (GMutex *mutex) +{ + g_mutex_lock (mutex); + return (GMutexLocker *) mutex; +} + +/** + * g_mutex_locker_free: + * @locker: a GMutexLocker + * + * Unlock @locker's mutex. See g_mutex_locker_new() for details. + * + * Since: 2.44 + */ +static inline void +g_mutex_locker_free (GMutexLocker *locker) +{ + g_mutex_unlock ((GMutex *) locker); +} + G_END_DECLS #endif /* __G_THREAD_H__ */