mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
macro wrappers for g_once_init_enter/leave
Give the macro wrapper treatment to g_once_init_enter() and leave() in the same style that we did for gatomic. It is now possible to use these macros with any pointer-sized object, and not just gsize. The leave() macro ensures that the initialisation result is a compatible type with the pointer that it is being written to. Just like with gatomic, there could be problems caused by use of (void*) casts. We'll see how that goes, and reevaluate if necessary. https://bugzilla.gnome.org/show_bug.cgi?id=660743
This commit is contained in:
parent
8f58c2c0c4
commit
794c1a30bc
@ -275,6 +275,13 @@ g_enumerable_thread_remove (GRealThread *thread)
|
|||||||
G_UNLOCK (g_thread);
|
G_UNLOCK (g_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GOnce {{{1 ------------------------------------------------------------- */
|
||||||
|
gboolean
|
||||||
|
g_once_init_enter_impl (volatile gsize *location)
|
||||||
|
{
|
||||||
|
return (g_once_init_enter) (location);
|
||||||
|
}
|
||||||
|
|
||||||
/* GStaticMutex {{{1 ------------------------------------------------------ */
|
/* GStaticMutex {{{1 ------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,6 +198,8 @@ void g_static_private_set (GStaticPrivate *private_key,
|
|||||||
GDestroyNotify notify);
|
GDestroyNotify notify);
|
||||||
void g_static_private_free (GStaticPrivate *private_key);
|
void g_static_private_free (GStaticPrivate *private_key);
|
||||||
|
|
||||||
|
gboolean g_once_init_enter_impl (volatile gsize *location);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_DEPRECATED_THREAD_H__ */
|
#endif /* __G_DEPRECATED_THREAD_H__ */
|
||||||
|
@ -753,8 +753,9 @@ g_once_impl (GOnce *once,
|
|||||||
* Since: 2.14
|
* Since: 2.14
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
g_once_init_enter_impl (volatile gsize *value_location)
|
(g_once_init_enter) (volatile void *pointer)
|
||||||
{
|
{
|
||||||
|
volatile gsize *value_location = pointer;
|
||||||
gboolean need_init = FALSE;
|
gboolean need_init = FALSE;
|
||||||
g_mutex_lock (&g_once_mutex);
|
g_mutex_lock (&g_once_mutex);
|
||||||
if (g_atomic_pointer_get (value_location) == NULL)
|
if (g_atomic_pointer_get (value_location) == NULL)
|
||||||
@ -777,7 +778,7 @@ g_once_init_enter_impl (volatile gsize *value_location)
|
|||||||
* g_once_init_leave:
|
* g_once_init_leave:
|
||||||
* @value_location: location of a static initializable variable
|
* @value_location: location of a static initializable variable
|
||||||
* containing 0
|
* containing 0
|
||||||
* @initialization_value: new non-0 value for *@value_location
|
* @result: new non-0 value for *@value_location
|
||||||
*
|
*
|
||||||
* Counterpart to g_once_init_enter(). Expects a location of a static
|
* Counterpart to g_once_init_enter(). Expects a location of a static
|
||||||
* 0-initialized initialization variable, and an initialization value
|
* 0-initialized initialization variable, and an initialization value
|
||||||
@ -788,14 +789,16 @@ g_once_init_enter_impl (volatile gsize *value_location)
|
|||||||
* Since: 2.14
|
* Since: 2.14
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
g_once_init_leave (volatile gsize *value_location,
|
(g_once_init_leave) (volatile void *pointer,
|
||||||
gsize initialization_value)
|
gsize result)
|
||||||
{
|
{
|
||||||
|
volatile gsize *value_location = pointer;
|
||||||
|
|
||||||
g_return_if_fail (g_atomic_pointer_get (value_location) == NULL);
|
g_return_if_fail (g_atomic_pointer_get (value_location) == NULL);
|
||||||
g_return_if_fail (initialization_value != 0);
|
g_return_if_fail (result != 0);
|
||||||
g_return_if_fail (g_once_init_list != NULL);
|
g_return_if_fail (g_once_init_list != NULL);
|
||||||
|
|
||||||
g_atomic_pointer_set (value_location, initialization_value);
|
g_atomic_pointer_set (value_location, result);
|
||||||
g_mutex_lock (&g_once_mutex);
|
g_mutex_lock (&g_once_mutex);
|
||||||
g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
|
g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
|
||||||
g_cond_broadcast (&g_once_cond);
|
g_cond_broadcast (&g_once_cond);
|
||||||
|
@ -154,21 +154,31 @@ gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg);
|
|||||||
g_once_impl ((once), (func), (arg)))
|
g_once_impl ((once), (func), (arg)))
|
||||||
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
|
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
|
||||||
|
|
||||||
/* initialize-once guards, keyed by value_location */
|
/* initialize-once guards, keyed by location */
|
||||||
G_INLINE_FUNC gboolean g_once_init_enter (volatile gsize *value_location);
|
gboolean g_once_init_enter (volatile void *location);
|
||||||
gboolean g_once_init_enter_impl (volatile gsize *value_location);
|
void g_once_init_leave (volatile void *location,
|
||||||
void g_once_init_leave (volatile gsize *value_location,
|
gsize result);
|
||||||
gsize initialization_value);
|
|
||||||
#if defined (G_CAN_INLINE) || defined (__G_THREAD_C__)
|
#ifdef __GNUC__
|
||||||
G_INLINE_FUNC gboolean
|
# define g_once_init_enter(location) \
|
||||||
g_once_init_enter (volatile gsize *value_location)
|
(G_GNUC_EXTENSION ({ \
|
||||||
{
|
G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
|
||||||
if G_LIKELY ((gpointer) g_atomic_pointer_get (value_location) != NULL)
|
(void) (0 ? (gpointer) *(location) : 0); \
|
||||||
return FALSE;
|
(!g_atomic_pointer_get (location) && \
|
||||||
else
|
g_once_init_enter (location)); \
|
||||||
return g_once_init_enter_impl (value_location);
|
}))
|
||||||
}
|
# define g_once_init_leave(location, result) \
|
||||||
#endif /* G_CAN_INLINE || __G_THREAD_C__ */
|
(G_GNUC_EXTENSION ({ \
|
||||||
|
G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
|
||||||
|
(void) (0 ? *(location) = (result) : 0); \
|
||||||
|
g_once_init_leave ((location), (gsize) (result)); \
|
||||||
|
}))
|
||||||
|
#else
|
||||||
|
# define g_once_init_enter(location) \
|
||||||
|
(g_once_init_enter((location)))
|
||||||
|
# define g_once_init_leave(location, result) \
|
||||||
|
(g_once_init_leave((location), (gsize) (result)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define G_LOCK_NAME(name) g__ ## name ## _lock
|
#define G_LOCK_NAME(name) g__ ## name ## _lock
|
||||||
#define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
|
#define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
|
||||||
|
@ -112,6 +112,17 @@ test_once3 (void)
|
|||||||
g_assert_cmpint (shared, ==, 42);
|
g_assert_cmpint (shared, ==, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_once4 (void)
|
||||||
|
{
|
||||||
|
static const gchar *val;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&val))
|
||||||
|
g_once_init_leave (&val, "foo");
|
||||||
|
|
||||||
|
g_assert_cmpstr (val, ==, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -120,6 +131,7 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/thread/once1", test_once1);
|
g_test_add_func ("/thread/once1", test_once1);
|
||||||
g_test_add_func ("/thread/once2", test_once2);
|
g_test_add_func ("/thread/once2", test_once2);
|
||||||
g_test_add_func ("/thread/once3", test_once3);
|
g_test_add_func ("/thread/once3", test_once3);
|
||||||
|
g_test_add_func ("/thread/once4", test_once4);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user