Revert "[build] Remove stale LDADD lines from tests/Makefile.am to allow build"
[platform/upstream/glib.git] / tests / refcount / properties3.c
1 #include <glib.h>
2 #include <glib-object.h>
3
4 #define G_TYPE_TEST                (my_test_get_type ())
5 #define MY_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
6 #define MY_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST))
7 #define MY_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass))
8 #define MY_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST))
9 #define MY_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass))
10
11 enum {
12   PROP_0,
13   PROP_DUMMY
14 };
15
16 typedef struct _GTest GTest;
17 typedef struct _GTestClass GTestClass;
18
19 struct _GTest
20 {
21   GObject object;
22   gint id;
23   gint dummy;
24
25   gint count;
26   gint setcount;
27 };
28
29 struct _GTestClass
30 {
31   GObjectClass parent_class;
32 };
33
34 G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT);
35
36 static volatile gboolean stopping;
37
38 static void my_test_get_property (GObject    *object,
39                                   guint       prop_id,
40                                   GValue     *value,
41                                   GParamSpec *pspec);
42 static void my_test_set_property (GObject      *object,
43                                   guint         prop_id,
44                                   const GValue *value,
45                                   GParamSpec   *pspec);
46
47 static void
48 my_test_class_init (GTestClass * klass)
49 {
50   GObjectClass *gobject_class;
51
52   gobject_class = (GObjectClass *) klass;
53
54   gobject_class->get_property = my_test_get_property;
55   gobject_class->set_property = my_test_set_property;
56
57   g_object_class_install_property (gobject_class,
58                                    PROP_DUMMY,
59                                    g_param_spec_int ("dummy",
60                                                      NULL,
61                                                      NULL,
62                                                      0, G_MAXINT, 0,
63                                                      G_PARAM_READWRITE));
64 }
65
66 static void
67 my_test_init (GTest * test)
68 {
69   static guint static_id = 1;
70   test->id = static_id++;
71 }
72
73 static void
74 my_test_get_property (GObject    *object,
75                       guint       prop_id,
76                       GValue     *value,
77                       GParamSpec *pspec)
78 {
79   GTest *test;
80
81   test = MY_TEST (object);
82
83   switch (prop_id)
84     {
85     case PROP_DUMMY:
86       g_value_set_int (value, g_atomic_int_get (&test->dummy));
87       break;
88     default:
89       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
90       break;
91     }
92 }
93
94 static void
95 my_test_set_property (GObject      *object,
96                       guint         prop_id,
97                       const GValue *value,
98                       GParamSpec   *pspec)
99 {
100   GTest *test;
101
102   test = MY_TEST (object);
103
104   switch (prop_id)
105     {
106     case PROP_DUMMY:
107       g_atomic_int_set (&test->dummy, g_value_get_int (value));
108       break;
109     default:
110       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
111       break;
112     }
113 }
114
115 static void
116 dummy_notify (GObject    *object,
117               GParamSpec *pspec)
118 {
119   GTest *test;
120
121   test = MY_TEST (object);
122
123   g_atomic_int_inc (&test->count);
124 }
125
126 static void
127 my_test_do_property (GTest * test)
128 {
129   gint dummy;
130
131   g_atomic_int_inc (&test->setcount);
132
133   g_object_get (test, "dummy", &dummy, NULL);
134   g_object_set (test, "dummy", dummy + 1, NULL);
135 }
136
137 static gpointer
138 run_thread (GTest * test)
139 {
140   gint i = 1;
141
142   while (!stopping) {
143     my_test_do_property (test);
144     if ((i++ % 10000) == 0)
145       {
146         g_print (".%c", 'a' + test->id);
147         g_thread_yield(); /* force context switch */
148       }
149   }
150
151   return NULL;
152 }
153
154 int
155 main (int argc, char **argv)
156 {
157   gint i;
158   GTest *test;
159   GArray *test_threads;
160   const gint n_threads = 5;
161
162   g_thread_init (NULL);
163
164   g_print ("START: %s\n", argv[0]);
165   g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK));
166   g_type_init ();
167
168   test = g_object_new (G_TYPE_TEST, NULL);
169
170   g_assert (test->count == test->dummy);
171   g_signal_connect (test, "notify::dummy", G_CALLBACK (dummy_notify), NULL);
172
173   test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *));
174
175   stopping = FALSE;
176
177   for (i = 0; i < n_threads; i++) {
178     GThread *thread;
179
180     thread = g_thread_create ((GThreadFunc) run_thread, test, TRUE, NULL);
181     g_array_append_val (test_threads, thread);
182   }
183   g_usleep (30000000);
184
185   stopping = TRUE;
186   g_print ("\nstopping\n");
187
188   /* join all threads */
189   for (i = 0; i < n_threads; i++) {
190     GThread *thread;
191
192     thread = g_array_index (test_threads, GThread *, i);
193     g_thread_join (thread);
194   }
195
196   g_print ("stopped\n");
197
198   g_print ("%d %d\n", test->setcount, test->count);
199
200   g_array_free (test_threads, TRUE);
201   g_object_unref (test);
202
203   return 0;
204 }