G_UNLOCK (g_thread);
}
+/* GOnce {{{1 ------------------------------------------------------------- */
+gboolean
+g_once_init_enter_impl (volatile gsize *location)
+{
+ return (g_once_init_enter) (location);
+}
+
/* GStaticMutex {{{1 ------------------------------------------------------ */
/**
GDestroyNotify notify);
void g_static_private_free (GStaticPrivate *private_key);
+gboolean g_once_init_enter_impl (volatile gsize *location);
+
G_END_DECLS
#endif /* __G_DEPRECATED_THREAD_H__ */
* Since: 2.14
*/
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;
g_mutex_lock (&g_once_mutex);
if (g_atomic_pointer_get (value_location) == NULL)
* g_once_init_leave:
* @value_location: location of a static initializable variable
* 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
* 0-initialized initialization variable, and an initialization value
* Since: 2.14
*/
void
-g_once_init_leave (volatile gsize *value_location,
- gsize initialization_value)
+(g_once_init_leave) (volatile void *pointer,
+ gsize result)
{
+ volatile gsize *value_location = pointer;
+
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_atomic_pointer_set (value_location, initialization_value);
+ g_atomic_pointer_set (value_location, result);
g_mutex_lock (&g_once_mutex);
g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
g_cond_broadcast (&g_once_cond);
g_once_impl ((once), (func), (arg)))
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
-/* initialize-once guards, keyed by value_location */
-G_INLINE_FUNC gboolean g_once_init_enter (volatile gsize *value_location);
-gboolean g_once_init_enter_impl (volatile gsize *value_location);
-void g_once_init_leave (volatile gsize *value_location,
- gsize initialization_value);
-#if defined (G_CAN_INLINE) || defined (__G_THREAD_C__)
-G_INLINE_FUNC gboolean
-g_once_init_enter (volatile gsize *value_location)
-{
- if G_LIKELY ((gpointer) g_atomic_pointer_get (value_location) != NULL)
- return FALSE;
- else
- return g_once_init_enter_impl (value_location);
-}
-#endif /* G_CAN_INLINE || __G_THREAD_C__ */
+/* initialize-once guards, keyed by location */
+gboolean g_once_init_enter (volatile void *location);
+void g_once_init_leave (volatile void *location,
+ gsize result);
+
+#ifdef __GNUC__
+# define g_once_init_enter(location) \
+ (G_GNUC_EXTENSION ({ \
+ G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
+ (void) (0 ? (gpointer) *(location) : 0); \
+ (!g_atomic_pointer_get (location) && \
+ g_once_init_enter (location)); \
+ }))
+# define g_once_init_leave(location, result) \
+ (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_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
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
main (int argc, char *argv[])
{
g_test_add_func ("/thread/once1", test_once1);
g_test_add_func ("/thread/once2", test_once2);
g_test_add_func ("/thread/once3", test_once3);
+ g_test_add_func ("/thread/once4", test_once4);
return g_test_run ();
}