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
00193 void
00194 dbus_message_handler_ref (DBusMessageHandler *handler)
00195 {
00196 _dbus_return_if_fail (handler != NULL);
00197
00198 _dbus_atomic_inc (&handler->refcount);
00199 }
00200
00207 void
00208 dbus_message_handler_unref (DBusMessageHandler *handler)
00209 {
00210 dbus_bool_t last_unref;
00211
00212 _dbus_return_if_fail (handler != NULL);
00213
00214 last_unref = (_dbus_atomic_dec (&handler->refcount) == 1);
00215
00216 if (last_unref)
00217 {
00218 DBusList *link;
00219
00220 if (handler->free_user_data)
00221 (* handler->free_user_data) (handler->user_data);
00222
00223 link = _dbus_list_get_first_link (&handler->connections);
00224 while (link != NULL)
00225 {
00226 DBusConnection *connection = link->data;
00227
00228 _dbus_connection_handler_destroyed_locked (connection, handler);
00229
00230 link = _dbus_list_get_next_link (&handler->connections, link);
00231 }
00232
00233 _dbus_list_clear (&handler->connections);
00234
00235 dbus_free (handler);
00236 }
00237 }
00238
00246 void*
00247 dbus_message_handler_get_data (DBusMessageHandler *handler)
00248 {
00249 void* user_data;
00250
00251 _dbus_return_val_if_fail (handler != NULL, NULL);
00252
00253 _DBUS_LOCK (message_handler);
00254 user_data = handler->user_data;
00255 _DBUS_UNLOCK (message_handler);
00256 return user_data;
00257 }
00258
00268 void
00269 dbus_message_handler_set_data (DBusMessageHandler *handler,
00270 void *user_data,
00271 DBusFreeFunction free_user_data)
00272 {
00273 DBusFreeFunction old_free_func;
00274 void *old_user_data;
00275
00276 _dbus_return_if_fail (handler != NULL);
00277
00278 _DBUS_LOCK (message_handler);
00279 old_free_func = handler->free_user_data;
00280 old_user_data = handler->user_data;
00281
00282 handler->user_data = user_data;
00283 handler->free_user_data = free_user_data;
00284 _DBUS_UNLOCK (message_handler);
00285
00286 if (old_free_func)
00287 (* old_free_func) (old_user_data);
00288
00289 }
00290
00298 void
00299 dbus_message_handler_set_function (DBusMessageHandler *handler,
00300 DBusHandleMessageFunction function)
00301 {
00302 _dbus_return_if_fail (handler != NULL);
00303
00304 _DBUS_LOCK (message_handler);
00305 handler->function = function;
00306 _DBUS_UNLOCK (message_handler);
00307 }
00308
00311 #ifdef DBUS_BUILD_TESTS
00312 static DBusHandlerResult
00313 test_handler (DBusMessageHandler *handler,
00314 DBusConnection *connection,
00315 DBusMessage *message,
00316 void *user_data)
00317 {
00318 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00319 }
00320
00321 static void
00322 free_test_data (void *data)
00323 {
00324
00325 }
00326
00333 dbus_bool_t
00334 _dbus_message_handler_test (const char *test_data_dir)
00335 {
00336 DBusMessageHandler *handler;
00337
00338 #define TEST_DATA ((void*) 0xcafebabe)
00339
00340 handler = dbus_message_handler_new (test_handler,
00341 TEST_DATA,
00342 free_test_data);
00343
00344 _dbus_assert (handler != NULL);
00345 _dbus_assert (handler->function == test_handler);
00346
00347 if (dbus_message_handler_get_data (handler) != TEST_DATA)
00348 _dbus_assert_not_reached ("got wrong data");
00349
00350 dbus_message_handler_set_data (handler, NULL, NULL);
00351 if (dbus_message_handler_get_data (handler) != NULL)
00352 _dbus_assert_not_reached ("got wrong data after set");
00353
00354 dbus_message_handler_set_function (handler, NULL);
00355 _dbus_assert (handler->function == NULL);
00356
00357 dbus_message_handler_ref (handler);
00358 dbus_message_handler_unref (handler);
00359 dbus_message_handler_unref (handler);
00360
00361 return TRUE;
00362 }
00363 #endif