[kdbus] sync with kdbus (kdbus.h - commit: 5ae1ecac44cb)
[platform/upstream/glib.git] / glib / tests / once.c
1
2 /* Unit tests for GOnce and friends
3  * Copyright (C) 2011 Red Hat, Inc
4  * Author: Matthias Clasen
5  *
6  * This work is provided "as is"; redistribution and modification
7  * in whole or in part, in any medium, physical or electronic is
8  * permitted without restriction.
9  *
10  * This work is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * In no event shall the authors or contributors be liable for any
15  * direct, indirect, incidental, special, exemplary, or consequential
16  * damages (including, but not limited to, procurement of substitute
17  * goods or services; loss of use, data, or profits; or business
18  * interruption) however caused and on any theory of liability, whether
19  * in contract, strict liability, or tort (including negligence or
20  * otherwise) arising in any way out of the use of this software, even
21  * if advised of the possibility of such damage.
22  */
23
24 #include <glib.h>
25
26 static gpointer
27 do_once (gpointer data)
28 {
29   static gint i = 0;
30
31   i++;
32
33   return GINT_TO_POINTER (i);
34 }
35
36 static void
37 test_once1 (void)
38 {
39   GOnce once = G_ONCE_INIT;
40   gpointer res;
41
42   g_assert (once.status == G_ONCE_STATUS_NOTCALLED);
43
44   res = g_once (&once, do_once, NULL);
45   g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1);
46
47   g_assert (once.status == G_ONCE_STATUS_READY);
48
49   res = g_once (&once, do_once, NULL);
50   g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1);
51 }
52
53 static void
54 test_once2 (void)
55 {
56   static gsize init = 0;
57
58   if (g_once_init_enter (&init))
59     {
60       g_assert (TRUE);
61       g_once_init_leave (&init, 1);
62     }
63
64   g_assert_cmpint (init, ==, 1);
65   if (g_once_init_enter (&init))
66     {
67       g_assert_not_reached ();
68       g_once_init_leave (&init, 2);
69     }
70   g_assert_cmpint (init, ==, 1);
71 }
72
73 #define THREADS 100
74
75 static gint64 shared;
76
77 static void
78 init_shared (void)
79 {
80   static gsize init = 0;
81
82   if (g_once_init_enter (&init))
83     {
84       shared += 42;
85
86       g_once_init_leave (&init, 1);
87     }
88 }
89
90 static gpointer
91 thread_func (gpointer data)
92 {
93   init_shared ();
94
95   return NULL;
96 }
97
98 static void
99 test_once3 (void)
100 {
101   gint i;
102   GThread *threads[THREADS];
103
104   shared = 0;
105
106   for (i = 0; i < THREADS; i++)
107     threads[i] = g_thread_new ("once3", thread_func, NULL);
108
109   for (i = 0; i < THREADS; i++)
110     g_thread_join (threads[i]);
111
112   g_assert_cmpint (shared, ==, 42);
113 }
114
115 static void
116 test_once4 (void)
117 {
118   static const gchar *val;
119
120   if (g_once_init_enter (&val))
121     g_once_init_leave (&val, "foo");
122
123   g_assert_cmpstr (val, ==, "foo");
124 }
125
126 int
127 main (int argc, char *argv[])
128 {
129   g_test_init (&argc, &argv, NULL);
130
131   g_test_add_func ("/thread/once1", test_once1);
132   g_test_add_func ("/thread/once2", test_once2);
133   g_test_add_func ("/thread/once3", test_once3);
134   g_test_add_func ("/thread/once4", test_once4);
135
136   return g_test_run ();
137 }