00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025
00026 #ifdef DBUS_BUILD_TESTS
00027 #include "test.h"
00028 #include <dbus/dbus-internals.h>
00029 #include <dbus/dbus-list.h>
00030
00031
00032
00033
00034
00035 static DBusList *clients = NULL;
00036 static DBusLoop *client_loop = NULL;
00037
00038 static dbus_bool_t
00039 client_watch_callback (DBusWatch *watch,
00040 unsigned int condition,
00041 void *data)
00042 {
00043
00044
00045
00046
00047
00048 return dbus_watch_handle (watch, condition);
00049 }
00050
00051 static dbus_bool_t
00052 add_client_watch (DBusWatch *watch,
00053 void *data)
00054 {
00055 DBusConnection *connection = data;
00056
00057 return _dbus_loop_add_watch (client_loop,
00058 watch, client_watch_callback, connection,
00059 NULL);
00060 }
00061
00062 static void
00063 remove_client_watch (DBusWatch *watch,
00064 void *data)
00065 {
00066 DBusConnection *connection = data;
00067
00068 _dbus_loop_remove_watch (client_loop,
00069 watch, client_watch_callback, connection);
00070 }
00071
00072 static void
00073 client_timeout_callback (DBusTimeout *timeout,
00074 void *data)
00075 {
00076 DBusConnection *connection = data;
00077
00078 dbus_connection_ref (connection);
00079
00080
00081 dbus_timeout_handle (timeout);
00082
00083 dbus_connection_unref (connection);
00084 }
00085
00086 static dbus_bool_t
00087 add_client_timeout (DBusTimeout *timeout,
00088 void *data)
00089 {
00090 DBusConnection *connection = data;
00091
00092 return _dbus_loop_add_timeout (client_loop, timeout, client_timeout_callback, connection, NULL);
00093 }
00094
00095 static void
00096 remove_client_timeout (DBusTimeout *timeout,
00097 void *data)
00098 {
00099 DBusConnection *connection = data;
00100
00101 _dbus_loop_remove_timeout (client_loop, timeout, client_timeout_callback, connection);
00102 }
00103
00104 static DBusHandlerResult
00105 client_disconnect_handler (DBusMessageHandler *handler,
00106 DBusConnection *connection,
00107 DBusMessage *message,
00108 void *user_data)
00109 {
00110 _dbus_verbose ("Removing client %p in disconnect handler\n",
00111 connection);
00112
00113 _dbus_list_remove (&clients, connection);
00114
00115 dbus_connection_unref (connection);
00116
00117 if (clients == NULL)
00118 {
00119 _dbus_loop_unref (client_loop);
00120 client_loop = NULL;
00121 }
00122
00123 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00124 }
00125
00126 static dbus_int32_t handler_slot = -1;
00127
00128 static void
00129 free_handler (void *data)
00130 {
00131 DBusMessageHandler *handler = data;
00132
00133 dbus_message_handler_unref (handler);
00134 dbus_connection_free_data_slot (&handler_slot);
00135 }
00136
00137 dbus_bool_t
00138 bus_setup_debug_client (DBusConnection *connection)
00139 {
00140 DBusMessageHandler *disconnect_handler;
00141 const char *to_handle[] = { DBUS_MESSAGE_LOCAL_DISCONNECT };
00142 dbus_bool_t retval;
00143
00144 disconnect_handler = dbus_message_handler_new (client_disconnect_handler,
00145 NULL, NULL);
00146
00147 if (disconnect_handler == NULL)
00148 return FALSE;
00149
00150 if (!dbus_connection_register_handler (connection,
00151 disconnect_handler,
00152 to_handle,
00153 _DBUS_N_ELEMENTS (to_handle)))
00154 {
00155 dbus_message_handler_unref (disconnect_handler);
00156 return FALSE;
00157 }
00158
00159 retval = FALSE;
00160
00161 if (client_loop == NULL)
00162 {
00163 client_loop = _dbus_loop_new ();
00164 if (client_loop == NULL)
00165 goto out;
00166 }
00167
00168 if (!dbus_connection_set_watch_functions (connection,
00169 add_client_watch,
00170 remove_client_watch,
00171 NULL,
00172 connection,
00173 NULL))
00174 goto out;
00175
00176 if (!dbus_connection_set_timeout_functions (connection,
00177 add_client_timeout,
00178 remove_client_timeout,
00179 NULL,
00180 connection, NULL))
00181 goto out;
00182
00183 if (!_dbus_list_append (&clients, connection))
00184 goto out;
00185
00186 if (!dbus_connection_allocate_data_slot (&handler_slot))
00187 goto out;
00188
00189
00190 if (!dbus_connection_set_data (connection, handler_slot,
00191 disconnect_handler,
00192 free_handler))
00193 {
00194 dbus_connection_free_data_slot (&handler_slot);
00195 goto out;
00196 }
00197
00198 retval = TRUE;
00199
00200 out:
00201 if (!retval)
00202 {
00203 dbus_message_handler_unref (disconnect_handler);
00204
00205 dbus_connection_set_watch_functions (connection,
00206 NULL, NULL, NULL, NULL, NULL);
00207 dbus_connection_set_timeout_functions (connection,
00208 NULL, NULL, NULL, NULL, NULL);
00209
00210 _dbus_list_remove_last (&clients, connection);
00211
00212 if (clients == NULL)
00213 {
00214 _dbus_loop_unref (client_loop);
00215 client_loop = NULL;
00216 }
00217 }
00218
00219 return retval;
00220 }
00221
00222 void
00223 bus_test_clients_foreach (BusConnectionForeachFunction function,
00224 void *data)
00225 {
00226 DBusList *link;
00227
00228 link = _dbus_list_get_first_link (&clients);
00229 while (link != NULL)
00230 {
00231 DBusConnection *connection = link->data;
00232 DBusList *next = _dbus_list_get_next_link (&clients, link);
00233
00234 if (!(* function) (connection, data))
00235 break;
00236
00237 link = next;
00238 }
00239 }
00240
00241 dbus_bool_t
00242 bus_test_client_listed (DBusConnection *connection)
00243 {
00244 DBusList *link;
00245
00246 link = _dbus_list_get_first_link (&clients);
00247 while (link != NULL)
00248 {
00249 DBusConnection *c = link->data;
00250 DBusList *next = _dbus_list_get_next_link (&clients, link);
00251
00252 if (c == connection)
00253 return TRUE;
00254
00255 link = next;
00256 }
00257
00258 return FALSE;
00259 }
00260
00261 void
00262 bus_test_run_clients_loop (dbus_bool_t block_once)
00263 {
00264 if (client_loop == NULL)
00265 return;
00266
00267
00268
00269
00270 _dbus_loop_dispatch (client_loop);
00271
00272
00273 if (block_once)
00274 {
00275 _dbus_verbose ("---> blocking on \"client side\"\n");
00276 _dbus_loop_iterate (client_loop, TRUE);
00277 }
00278
00279
00280 while (_dbus_loop_iterate (client_loop, FALSE))
00281 ;
00282 }
00283
00284 void
00285 bus_test_run_bus_loop (BusContext *context,
00286 dbus_bool_t block_once)
00287 {
00288
00289
00290
00291 _dbus_loop_dispatch (bus_context_get_loop (context));
00292
00293
00294 if (block_once)
00295 {
00296 _dbus_verbose ("---> blocking on \"server side\"\n");
00297 _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
00298 }
00299
00300
00301 while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
00302 ;
00303 }
00304
00305 void
00306 bus_test_run_everything (BusContext *context)
00307 {
00308 while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
00309 (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
00310 ;
00311 }
00312
00313 BusContext*
00314 bus_context_new_test (const DBusString *test_data_dir,
00315 const char *filename)
00316 {
00317 DBusError error;
00318 DBusString config_file;
00319 DBusString relative;
00320 BusContext *context;
00321
00322 if (!_dbus_string_init (&config_file))
00323 {
00324 _dbus_warn ("No memory\n");
00325 return NULL;
00326 }
00327
00328 if (!_dbus_string_copy (test_data_dir, 0,
00329 &config_file, 0))
00330 {
00331 _dbus_warn ("No memory\n");
00332 _dbus_string_free (&config_file);
00333 return NULL;
00334 }
00335
00336 _dbus_string_init_const (&relative, filename);
00337
00338 if (!_dbus_concat_dir_and_file (&config_file, &relative))
00339 {
00340 _dbus_warn ("No memory\n");
00341 _dbus_string_free (&config_file);
00342 return NULL;
00343 }
00344
00345 dbus_error_init (&error);
00346 context = bus_context_new (&config_file, FALSE, -1, -1, &error);
00347 if (context == NULL)
00348 {
00349 _DBUS_ASSERT_ERROR_IS_SET (&error);
00350
00351 _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
00352 filename, error.message);
00353
00354 dbus_error_free (&error);
00355
00356 _dbus_string_free (&config_file);
00357
00358 return NULL;
00359 }
00360
00361 _dbus_string_free (&config_file);
00362
00363 return context;
00364 }
00365
00366 #endif