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
_run_iteration(DBusConnection * conn)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
check_mutex_lock(DBusMutex * mutex1,DBusMutex * mutex2,dbus_bool_t is_same)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
check_condvar_lock(DBusCondVar * condvar1,DBusCondVar * condvar2,dbus_bool_t is_same)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
main(int argc,char * argv[])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 check_mutex_lock (mutex1, mutex2, FALSE);
153 check_mutex_lock (dispatch_mutex1, dispatch_mutex2, FALSE);
154 check_mutex_lock (io_path_mutex1, io_path_mutex2, FALSE);
155 check_condvar_lock (dispatch_cond1, dispatch_cond2, FALSE);
156 check_condvar_lock (io_path_cond1, io_path_cond2, FALSE);
157
158 _run_iteration (conn);
159 _dbus_connection_test_get_locks (conn, &mutex2,
160 &dispatch_mutex2,
161 &io_path_mutex2,
162 &dispatch_cond2,
163 &io_path_cond2);
164
165 check_mutex_lock (mutex1, mutex2, TRUE);
166 check_mutex_lock (dispatch_mutex1, dispatch_mutex2, TRUE);
167 check_mutex_lock (io_path_mutex1, io_path_mutex2, TRUE);
168 check_condvar_lock (dispatch_cond1, dispatch_cond2, TRUE);
169 check_condvar_lock (io_path_cond1, io_path_cond2, TRUE);
170
171 method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
172 "/org/freedesktop/TestSuite",
173 "org.freedesktop.TestSuite",
174 "Exit");
175 dbus_connection_send (conn, method, NULL);
176 dbus_message_unref (method);
177
178 printf ("Success ***\n");
179 exit (0);
180 }
181