Merge branch 'dbus-1.6'
[platform/upstream/dbus.git] / test / name-test / test-threads-init.c
1 /**
2  * Test to make sure late thread initialization works
3  */
4
5 #include <config.h>
6 #include <dbus/dbus.h>
7 #include <dbus/dbus-sysdeps.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include <dbus/dbus-internals.h>
12 #include <dbus/dbus-connection-internal.h>
13
14 static void
15 _run_iteration (DBusConnection *conn)
16 {
17   DBusPendingCall *echo_pending;
18   DBusPendingCall *dbus_pending;
19   DBusMessage *method;
20   DBusMessage *reply;
21   char *echo = "echo";
22
23   /* send the first message */
24   method = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
25                                          "/org/freedesktop/TestSuite",
26                                          "org.freedesktop.TestSuite",
27                                          "Echo");
28
29   dbus_message_append_args (method, DBUS_TYPE_STRING, &echo, NULL);
30   dbus_connection_send_with_reply (conn, method, &echo_pending, -1);
31   dbus_message_unref (method);
32   
33   /* send the second message */
34   method = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
35                                          DBUS_PATH_DBUS,
36                                          "org.freedesktop.Introspectable",
37                                          "Introspect");
38
39   dbus_connection_send_with_reply (conn, method, &dbus_pending, -1);
40   dbus_message_unref (method);
41
42   /* block on the second message (should return immediately) */
43   dbus_pending_call_block (dbus_pending);
44
45   /* block on the first message */
46   /* if it does not return immediately chances 
47      are we hit the block in poll bug */
48   dbus_pending_call_block (echo_pending);
49
50   /* check the reply only to make sure we
51      are not getting errors unrelated
52      to the block in poll bug */
53   reply = dbus_pending_call_steal_reply (echo_pending);
54
55   if (reply == NULL)
56     {
57       printf ("Failed: Reply is NULL ***\n");
58       exit (1);
59     }
60
61   if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
62     {
63       printf ("Failed: Reply is error: %s ***\n", dbus_message_get_error_name (reply));
64       exit (1);
65     } 
66
67   dbus_message_unref (reply);
68   dbus_pending_call_unref (dbus_pending);
69   dbus_pending_call_unref (echo_pending);
70   
71 }
72 static void
73 check_mutex_lock (DBusMutex *mutex1, 
74                   DBusMutex *mutex2, 
75                   dbus_bool_t is_same)
76 {
77   _dbus_assert (mutex1 != NULL);
78   _dbus_assert (mutex2 != NULL);
79   
80   if (is_same)
81     {
82       _dbus_assert (mutex1 == mutex2);
83     }
84   else
85     {
86       _dbus_assert (mutex1 != mutex2);
87     }
88 }
89
90 static void
91 check_condvar_lock (DBusCondVar *condvar1,  
92                     DBusCondVar *condvar2,   
93                     dbus_bool_t is_same)
94 {
95   _dbus_assert (condvar1 != NULL);
96   _dbus_assert (condvar2 != NULL);
97
98   if (is_same)
99     {
100       _dbus_assert (condvar1 == condvar2);
101     }
102   else
103     {
104       _dbus_assert (condvar1 != condvar2);
105     }
106 }
107
108
109 int
110 main (int argc, char *argv[])
111 {
112   DBusMessage *method;
113   DBusConnection *conn;
114   DBusError error;
115   DBusMutex *mutex1, *dispatch_mutex1, *io_path_mutex1;
116   DBusCondVar *dispatch_cond1, *io_path_cond1;
117   DBusMutex *mutex2, *dispatch_mutex2, *io_path_mutex2;
118   DBusCondVar *dispatch_cond2, *io_path_cond2;
119
120   printf ("*** Testing late thread init\n");
121
122   dbus_error_init (&error);
123
124   conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
125
126   _dbus_connection_test_get_locks (conn, &mutex1, 
127                                          &dispatch_mutex1, 
128                                          &io_path_mutex1,
129                                          &dispatch_cond1,
130                                          &io_path_cond1);
131   _run_iteration (conn);
132   _dbus_connection_test_get_locks (conn, &mutex2,
133                                          &dispatch_mutex2,
134                                          &io_path_mutex2,
135                                          &dispatch_cond2,
136                                          &io_path_cond2);
137
138   check_mutex_lock (mutex1, mutex2, TRUE);
139   check_mutex_lock (dispatch_mutex1, dispatch_mutex2, TRUE);
140   check_mutex_lock (io_path_mutex1, io_path_mutex2, TRUE);
141   check_condvar_lock (dispatch_cond1, dispatch_cond2, TRUE);
142   check_condvar_lock (io_path_cond1, io_path_cond2, TRUE);
143
144   dbus_threads_init_default ();
145
146   _dbus_connection_test_get_locks (conn, &mutex1,
147                                          &dispatch_mutex1,
148                                          &io_path_mutex1,
149                                          &dispatch_cond1,
150                                          &io_path_cond1);
151
152   /* Since 1.7 it is no longer the case that mutex1 != mutex2, because
153    * initializing global locks automatically initializes locks
154    * in general. However, it is true that the mutex is not the dummy
155    * implementation, which is what we really wanted to check here. */
156   _dbus_assert (mutex1 != (DBusMutex *) 0xABCDEF);
157   _dbus_assert (dispatch_mutex1 != (DBusMutex *) 0xABCDEF);
158   _dbus_assert (dispatch_cond1 != (DBusCondVar *) 0xABCDEF2);
159   _dbus_assert (io_path_mutex1 != (DBusMutex *) 0xABCDEF);
160   _dbus_assert (io_path_cond1 != (DBusCondVar *) 0xABCDEF2);
161
162   _run_iteration (conn);
163   _dbus_connection_test_get_locks (conn, &mutex2,
164                                          &dispatch_mutex2,
165                                          &io_path_mutex2,
166                                          &dispatch_cond2,
167                                          &io_path_cond2);
168
169   check_mutex_lock (mutex1, mutex2, TRUE);
170   check_mutex_lock (dispatch_mutex1, dispatch_mutex2, TRUE);
171   check_mutex_lock (io_path_mutex1, io_path_mutex2, TRUE);
172   check_condvar_lock (dispatch_cond1, dispatch_cond2, TRUE);
173   check_condvar_lock (io_path_cond1, io_path_cond2, TRUE);
174
175   method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
176                                          "/org/freedesktop/TestSuite",
177                                          "org.freedesktop.TestSuite",
178                                          "Exit");
179   dbus_connection_send (conn, method, NULL);
180   dbus_message_unref (method);
181
182   printf ("Success ***\n");
183   exit (0);
184 }