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 "dbus-internals.h"
00025 #include "dbus-message-handler.h"
00026 #include "dbus-list.h"
00027 #include "dbus-threads.h"
00028 #include "dbus-test.h"
00029 #include "dbus-connection-internal.h"
00030
00041 _DBUS_DEFINE_GLOBAL_LOCK (message_handler);
00042
00048 struct DBusMessageHandler
00049 {
00050 DBusAtomic refcount;
00052 DBusHandleMessageFunction function;
00053 void *user_data;
00054 DBusFreeFunction free_user_data;
00056 DBusList *connections;
00057 };
00058
00068 dbus_bool_t
00069 _dbus_message_handler_add_connection (DBusMessageHandler *handler,
00070 DBusConnection *connection)
00071 {
00072 dbus_bool_t res;
00073
00074 _DBUS_LOCK (message_handler);
00075
00076
00077
00078 if (!_dbus_list_prepend (&handler->connections, connection))
00079 res = FALSE;
00080 else
00081 res = TRUE;
00082
00083 _DBUS_UNLOCK (message_handler);
00084
00085 return res;
00086 }
00087
00093 void
00094 _dbus_message_handler_remove_connection (DBusMessageHandler *handler,
00095 DBusConnection *connection)
00096 {
00097 _DBUS_LOCK (message_handler);
00098 if (!_dbus_list_remove (&handler->connections, connection))
00099 _dbus_warn ("Function _dbus_message_handler_remove_connection() called when the connection hadn't been added\n");
00100 _DBUS_UNLOCK (message_handler);
00101 }
00102
00103
00114 DBusHandlerResult
00115 _dbus_message_handler_handle_message (DBusMessageHandler *handler,
00116 DBusConnection *connection,
00117 DBusMessage *message)
00118 {
00119 DBusHandleMessageFunction function;
00120 void *user_data;
00121
00122 _DBUS_LOCK (message_handler);
00123 function = handler->function;
00124 user_data = handler->user_data;
00125 _DBUS_UNLOCK (message_handler);
00126
00127
00128
00129
00130 if (function != NULL)
00131 return (* function) (handler, connection, message, user_data);
00132 else
00133 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00134 }
00135
00167 DBusMessageHandler*
00168 dbus_message_handler_new (DBusHandleMessageFunction function,
00169 void *user_data,
00170 DBusFreeFunction free_user_data)
00171 {
00172 DBusMessageHandler *handler;
00173
00174 handler = dbus_new (DBusMessageHandler, 1);
00175
00176 if (handler == NULL)
00177 return NULL;
00178
00179 handler->refcount.value = 1;
00180 handler->function = function;
00181 handler->user_data = user_data;
00182 handler->free_user_data = free_user_data;
00183 handler->connections = NULL;
00184
00185 return handler;
00186 }
00187
00194 DBusMessageHandler *
00195 dbus_message_handler_ref (DBusMessageHandler *handler)
00196 {
00197 _dbus_return_if_fail (handler != NULL);
00198
00199 _dbus_atomic_inc (&handler->refcount);
00200
00201 return handler;
00202 }
00203
00210 void
00211 dbus_message_handler_unref (DBusMessageHandler *handler)
00212 {
00213 dbus_bool_t last_unref;
00214
00215 _dbus_return_if_fail (handler != NULL);
00216
00217 last_unref = (_dbus_atomic_dec (&handler->refcount) == 1);
00218
00219 if (last_unref)
00220 {
00221 DBusList *link;
00222
00223 if (handler->free_user_data)
00224 (* handler->free_user_data) (handler->user_data);
00225
00226 link = _dbus_list_get_first_link (&handler->connections);
00227 while (link != NULL)
00228 {
00229 DBusConnection *connection = link->data;
00230
00231 _dbus_connection_handler_destroyed_locked (connection, handler);
00232
00233 link = _dbus_list_get_next_link (&handler->connections, link);
00234 }
00235
00236 _dbus_list_clear (&handler->connections);
00237
00238 dbus_free (handler);
00239 }
00240 }
00241
00249 void*
00250 dbus_message_handler_get_data (DBusMessageHandler *handler)
00251 {
00252 void* user_data;
00253
00254 _dbus_return_val_if_fail (handler != NULL, NULL);
00255
00256 _DBUS_LOCK (message_handler);
00257 user_data = handler->user_data;
00258 _DBUS_UNLOCK (message_handler);
00259 return user_data;
00260 }
00261
00271 void
00272 dbus_message_handler_set_data (DBusMessageHandler *handler,
00273 void *user_data,
00274 DBusFreeFunction free_user_data)
00275 {
00276 DBusFreeFunction old_free_func;
00277 void *old_user_data;
00278
00279 _dbus_return_if_fail (handler != NULL);
00280
00281 _DBUS_LOCK (message_handler);
00282 old_free_func = handler->free_user_data;
00283 old_user_data = handler->user_data;
00284
00285 handler->user_data = user_data;
00286 handler->free_user_data = free_user_data;
00287 _DBUS_UNLOCK (message_handler);
00288
00289 if (old_free_func)
00290 (* old_free_func) (old_user_data);
00291
00292 }
00293
00301 void
00302 dbus_message_handler_set_function (DBusMessageHandler *handler,
00303 DBusHandleMessageFunction function)
00304 {
00305 _dbus_return_if_fail (handler != NULL);
00306
00307 _DBUS_LOCK (message_handler);
00308 handler->function = function;
00309 _DBUS_UNLOCK (message_handler);
00310 }
00311
00314 #ifdef DBUS_BUILD_TESTS
00315 static DBusHandlerResult
00316 test_handler (DBusMessageHandler *handler,
00317 DBusConnection *connection,
00318 DBusMessage *message,
00319 void *user_data)
00320 {
00321 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00322 }
00323
00324 static void
00325 free_test_data (void *data)
00326 {
00327
00328 }
00329
00336 dbus_bool_t
00337 _dbus_message_handler_test (const char *test_data_dir)
00338 {
00339 DBusMessageHandler *handler;
00340
00341 #define TEST_DATA ((void*) 0xcafebabe)
00342
00343 handler = dbus_message_handler_new (test_handler,
00344 TEST_DATA,
00345 free_test_data);
00346
00347 _dbus_assert (handler != NULL);
00348 _dbus_assert (handler->function == test_handler);
00349
00350 if (dbus_message_handler_get_data (handler) != TEST_DATA)
00351 _dbus_assert_not_reached ("got wrong data");
00352
00353 dbus_message_handler_set_data (handler, NULL, NULL);
00354 if (dbus_message_handler_get_data (handler) != NULL)
00355 _dbus_assert_not_reached ("got wrong data after set");
00356
00357 dbus_message_handler_set_function (handler, NULL);
00358 _dbus_assert (handler->function == NULL);
00359
00360 dbus_message_handler_ref (handler);
00361 dbus_message_handler_unref (handler);
00362 dbus_message_handler_unref (handler);
00363
00364 return TRUE;
00365 }
00366 #endif