1 #include <config.h> 2 #include "test-utils.h" 3 4 typedef struct 5 { 6 DBusLoop *loop; 7 DBusConnection *connection; 8 9 } CData; 10 11 static dbus_bool_t 12 connection_watch_callback (DBusWatch *watch, 13 unsigned int condition, 14 void *data) 15 { 16 return dbus_watch_handle (watch, condition); 17 } 18 19 static dbus_bool_t 20 add_watch (DBusWatch *watch, 21 void *data) 22 { 23 CData *cd = data; 24 25 return _dbus_loop_add_watch (cd->loop, 26 watch, 27 connection_watch_callback, 28 cd, NULL); 29 } 30 31 static void 32 remove_watch (DBusWatch *watch, 33 void *data) 34 { 35 CData *cd = data; 36 37 _dbus_loop_remove_watch (cd->loop, 38 watch, connection_watch_callback, cd); 39 } 40 41 static void 42 connection_timeout_callback (DBusTimeout *timeout, 43 void *data) 44 { 45 /* Can return FALSE on OOM but we just let it fire again later */ 46 dbus_timeout_handle (timeout); 47 } 48 49 static dbus_bool_t 50 add_timeout (DBusTimeout *timeout, 51 void *data) 52 { 53 CData *cd = data; 54 55 return _dbus_loop_add_timeout (cd->loop, 56 timeout, connection_timeout_callback, cd, NULL); 57 } 58 59 static void 60 remove_timeout (DBusTimeout *timeout, 61 void *data) 62 { 63 CData *cd = data; 64 65 _dbus_loop_remove_timeout (cd->loop, 66 timeout, connection_timeout_callback, cd); 67 } 68 69 static void 70 dispatch_status_function (DBusConnection *connection, 71 DBusDispatchStatus new_status, 72 void *data) 73 { 74 DBusLoop *loop = data; 75 76 if (new_status != DBUS_DISPATCH_COMPLETE) 77 { 78 while (!_dbus_loop_queue_dispatch (loop, connection)) 79 _dbus_wait_for_memory (); 80 } 81 } 82 83 static void 84 cdata_free (void *data) 85 { 86 CData *cd = data; 87 88 dbus_connection_unref (cd->connection); 89 _dbus_loop_unref (cd->loop); 90 91 dbus_free (cd); 92 } 93 94 static CData* 95 cdata_new (DBusLoop *loop, 96 DBusConnection *connection) 97 { 98 CData *cd; 99 100 cd = dbus_new0 (CData, 1); 101 if (cd == NULL) 102 return NULL; 103 104 cd->loop = loop; 105 cd->connection = connection; 106 107 dbus_connection_ref (cd->connection); 108 _dbus_loop_ref (cd->loop); 109 110 return cd; 111 } 112 113 dbus_bool_t 114 test_connection_setup (DBusLoop *loop, 115 DBusConnection *connection) 116 { 117 CData *cd; 118 119 cd = NULL; 120 121 dbus_connection_set_dispatch_status_function (connection, dispatch_status_function, 122 loop, NULL); 123 124 cd = cdata_new (loop, connection); 125 if (cd == NULL) 126 goto nomem; 127 128 /* Because dbus-mainloop.c checks dbus_timeout_get_enabled(), 129 * dbus_watch_get_enabled() directly, we don't have to provide 130 * "toggled" callbacks. 131 */ 132 133 if (!dbus_connection_set_watch_functions (connection, 134 add_watch, 135 remove_watch, 136 NULL, 137 cd, cdata_free)) 138 goto nomem; 139 140 141 cd = cdata_new (loop, connection); 142 if (cd == NULL) 143 goto nomem; 144 145 if (!dbus_connection_set_timeout_functions (connection, 146 add_timeout, 147 remove_timeout, 148 NULL, 149 cd, cdata_free)) 150 goto nomem; 151 152 if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE) 153 { 154 if (!_dbus_loop_queue_dispatch (loop, connection)) 155 goto nomem; 156 } 157 158 return TRUE; 159 160 nomem: 161 if (cd) 162 cdata_free (cd); 163 164 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL); 165 dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL); 166 dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL); 167 168 return FALSE; 169 } 170 171 void 172 test_connection_shutdown (DBusLoop *loop, 173 DBusConnection *connection) 174 { 175 if (!dbus_connection_set_watch_functions (connection, 176 NULL, 177 NULL, 178 NULL, 179 NULL, NULL)) 180 _dbus_assert_not_reached ("setting watch functions to NULL failed"); 181 182 if (!dbus_connection_set_timeout_functions (connection, 183 NULL, 184 NULL, 185 NULL, 186 NULL, NULL)) 187 _dbus_assert_not_reached ("setting timeout functions to NULL failed"); 188 189 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL); 190 } 191 192 typedef struct 193 { 194 DBusLoop *loop; 195 DBusServer *server; 196 } ServerData; 197 198 static void 199 serverdata_free (void *data) 200 { 201 ServerData *sd = data; 202 203 dbus_server_unref (sd->server); 204 _dbus_loop_unref (sd->loop); 205 206 dbus_free (sd); 207 } 208 209 static ServerData* 210 serverdata_new (DBusLoop *loop, 211 DBusServer *server) 212 { 213 ServerData *sd; 214 215 sd = dbus_new0 (ServerData, 1); 216 if (sd == NULL) 217 return NULL; 218 219 sd->loop = loop; 220 sd->server = server; 221 222 dbus_server_ref (sd->server); 223 _dbus_loop_ref (sd->loop); 224 225 return sd; 226 } 227 228 static dbus_bool_t 229 server_watch_callback (DBusWatch *watch, 230 unsigned int condition, 231 void *data) 232 { 233 /* FIXME this can be done in dbus-mainloop.c 234 * if the code in activation.c for the babysitter 235 * watch handler is fixed. 236 */ 237 238 return dbus_watch_handle (watch, condition); 239 } 240 241 static dbus_bool_t 242 add_server_watch (DBusWatch *watch, 243 void *data) 244 { 245 ServerData *context = data; 246 247 return _dbus_loop_add_watch (context->loop, 248 watch, server_watch_callback, context, 249 NULL); 250 } 251 252 static void 253 remove_server_watch (DBusWatch *watch, 254 void *data) 255 { 256 ServerData *context = data; 257 258 _dbus_loop_remove_watch (context->loop, 259 watch, server_watch_callback, context); 260 } 261 262 static void 263 server_timeout_callback (DBusTimeout *timeout, 264 void *data) 265 { 266 /* can return FALSE on OOM but we just let it fire again later */ 267 dbus_timeout_handle (timeout); 268 } 269 270 static dbus_bool_t 271 add_server_timeout (DBusTimeout *timeout, 272 void *data) 273 { 274 ServerData *context = data; 275 276 return _dbus_loop_add_timeout (context->loop, 277 timeout, server_timeout_callback, context, NULL); 278 } 279 280 static void 281 remove_server_timeout (DBusTimeout *timeout, 282 void *data) 283 { 284 ServerData *context = data; 285 286 _dbus_loop_remove_timeout (context->loop, 287 timeout, server_timeout_callback, context); 288 } 289 290 dbus_bool_t 291 test_server_setup (DBusLoop *loop, 292 DBusServer *server) 293 { 294 ServerData *sd; 295 296 sd = serverdata_new (loop, server); 297 if (sd == NULL) 298 goto nomem; 299 300 if (!dbus_server_set_watch_functions (server, 301 add_server_watch, 302 remove_server_watch, 303 NULL, 304 sd, 305 serverdata_free)) 306 { 307 return FALSE; 308 } 309 310 if (!dbus_server_set_timeout_functions (server, 311 add_server_timeout, 312 remove_server_timeout, 313 NULL, 314 sd, serverdata_free)) 315 { 316 return FALSE; 317 } 318 return TRUE; 319 320 nomem: 321 if (sd) 322 serverdata_free (sd); 323 324 test_server_shutdown (loop, server); 325 326 return FALSE; 327 } 328 329 void 330 test_server_shutdown (DBusLoop *loop, 331 DBusServer *server) 332 { 333 if (!dbus_server_set_watch_functions (server, 334 NULL, NULL, NULL, 335 NULL, 336 NULL)) 337 _dbus_assert_not_reached ("setting watch functions to NULL failed"); 338 339 if (!dbus_server_set_timeout_functions (server, 340 NULL, NULL, NULL, 341 NULL, 342 NULL)) 343 _dbus_assert_not_reached ("setting timeout functions to NULL failed"); 344 } 345