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