1#include <config.h> 2#include "test-utils.h" 3 4typedef struct 5{ 6 DBusLoop *loop; 7 DBusConnection *connection; 8 9} CData; 10 11static dbus_bool_t 12connection_watch_callback (DBusWatch *watch, 13 unsigned int condition, 14 void *data) 15{ 16 return dbus_watch_handle (watch, condition); 17} 18 19static dbus_bool_t 20add_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 31static void 32remove_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 41static void 42connection_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 49static dbus_bool_t 50add_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 59static void 60remove_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 69static void 70dispatch_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 83static void 84cdata_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 94static CData* 95cdata_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 113dbus_bool_t 114test_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 171void 172test_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 192typedef struct 193{ 194 DBusLoop *loop; 195 DBusServer *server; 196} ServerData; 197 198static void 199serverdata_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 209static ServerData* 210serverdata_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 228static dbus_bool_t 229server_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 241static dbus_bool_t 242add_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 252static void 253remove_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 262static void 263server_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 270static dbus_bool_t 271add_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 280static void 281remove_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 290dbus_bool_t 291test_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 329void 330test_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