1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message-handler.c Sender/receiver of messages.
4 * Copyright (C) 2002 Red Hat Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-internals.h"
25 #include "dbus-message-handler.h"
26 #include "dbus-list.h"
27 #include "dbus-threads.h"
28 #include "dbus-connection-internal.h"
31 * @defgroup DBusMessageHandlerInternals DBusMessageHandler implementation details
32 * @ingroup DBusInternals
33 * @brief DBusMessageHandler private implementation details.
35 * The guts of DBusMessageHandler and its methods.
40 _DBUS_DEFINE_GLOBAL_LOCK (message_handler);
43 * @brief Internals of DBusMessageHandler
45 * Object that can send and receive messages.
47 struct DBusMessageHandler
49 int refcount; /**< reference count */
51 DBusHandleMessageFunction function; /**< handler function */
52 void *user_data; /**< user data for function */
53 DBusFreeFunction free_user_data; /**< free the user data */
55 DBusList *connections; /**< connections we're registered with */
59 * Add this connection to the list used by this message handler.
60 * When the message handler goes away, the connection
63 * @param handler the message handler
64 * @param connection the connection
65 * @returns #FALSE if not enough memory
68 _dbus_message_handler_add_connection (DBusMessageHandler *handler,
69 DBusConnection *connection)
73 _DBUS_LOCK (message_handler);
74 /* This is a bit wasteful - we just put the connection in the list
75 * once per time it's added. :-/
77 if (!_dbus_list_prepend (&handler->connections, connection))
82 _DBUS_UNLOCK (message_handler);
88 * Reverses the effect of _dbus_message_handler_add_connection().
89 * @param handler the message handler
90 * @param connection the connection
93 _dbus_message_handler_remove_connection (DBusMessageHandler *handler,
94 DBusConnection *connection)
96 _DBUS_LOCK (message_handler);
97 if (!_dbus_list_remove (&handler->connections, connection))
98 _dbus_warn ("Function _dbus_message_handler_remove_connection() called when the connection hadn't been added\n");
99 _DBUS_UNLOCK (message_handler);
104 * Handles the given message, by dispatching the handler function
105 * for this DBusMessageHandler, if any.
107 * @param handler the handler
108 * @param connection the connection that received the message
109 * @param message the message
111 * @returns what to do with the message
114 _dbus_message_handler_handle_message (DBusMessageHandler *handler,
115 DBusConnection *connection,
116 DBusMessage *message)
118 DBusHandleMessageFunction function;
121 _DBUS_LOCK (message_handler);
122 function = handler->function;
123 user_data = handler->user_data;
124 _DBUS_UNLOCK (message_handler);
126 /* This function doesn't ref handler/connection/message
127 * since that's done in dbus_connection_dispatch().
129 if (function != NULL)
130 return (* function) (handler, connection, message, user_data);
132 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
138 * @defgroup DBusMessageHandler DBusMessageHandler
140 * @brief Message processor
142 * A DBusMessageHandler is an object that can send and receive
143 * messages. Typically the handler is registered with one or
144 * more DBusConnection objects and processes some types of
145 * messages received from the connection.
151 * @typedef DBusMessageHandler
153 * Opaque data type representing a message handler.
157 * Creates a new message handler. The handler function
158 * may be #NULL for a no-op handler or a handler to
159 * be assigned a function later.
161 * @param function function to call to handle a message
162 * @param user_data data to pass to the function
163 * @param free_user_data function to call to free the user data
164 * @returns a new DBusMessageHandler or #NULL if no memory.
167 dbus_message_handler_new (DBusHandleMessageFunction function,
169 DBusFreeFunction free_user_data)
171 DBusMessageHandler *handler;
173 handler = dbus_new (DBusMessageHandler, 1);
178 handler->refcount = 1;
179 handler->function = function;
180 handler->user_data = user_data;
181 handler->free_user_data = free_user_data;
182 handler->connections = NULL;
188 * Increments the reference count on a message handler.
190 * @param handler the handler
193 dbus_message_handler_ref (DBusMessageHandler *handler)
195 _dbus_return_if_fail (handler != NULL);
197 _DBUS_LOCK (message_handler);
198 _dbus_assert (handler != NULL);
200 handler->refcount += 1;
201 _DBUS_UNLOCK (message_handler);
205 * Decrements the reference count on a message handler,
206 * freeing the handler if the count reaches 0.
208 * @param handler the handler
211 dbus_message_handler_unref (DBusMessageHandler *handler)
215 _dbus_return_if_fail (handler != NULL);
217 _DBUS_LOCK (message_handler);
219 _dbus_assert (handler != NULL);
220 _dbus_assert (handler->refcount > 0);
222 handler->refcount -= 1;
223 refcount = handler->refcount;
225 _DBUS_UNLOCK (message_handler);
231 if (handler->free_user_data)
232 (* handler->free_user_data) (handler->user_data);
234 link = _dbus_list_get_first_link (&handler->connections);
237 DBusConnection *connection = link->data;
239 _dbus_connection_handler_destroyed_locked (connection, handler);
241 link = _dbus_list_get_next_link (&handler->connections, link);
244 _dbus_list_clear (&handler->connections);
251 * Gets the user data for the handler (the same user data
252 * passed to the handler function.)
254 * @param handler the handler
255 * @returns the user data
258 dbus_message_handler_get_data (DBusMessageHandler *handler)
262 _dbus_return_val_if_fail (handler != NULL, NULL);
264 _DBUS_LOCK (message_handler);
265 user_data = handler->user_data;
266 _DBUS_UNLOCK (message_handler);
271 * Sets the user data for the handler (the same user data
272 * to be passed to the handler function). Frees any previously-existing
273 * user data with the previous free_user_data function.
275 * @param handler the handler
276 * @param user_data the user data
277 * @param free_user_data free function for the data
280 dbus_message_handler_set_data (DBusMessageHandler *handler,
282 DBusFreeFunction free_user_data)
284 DBusFreeFunction old_free_func;
287 _dbus_return_if_fail (handler != NULL);
289 _DBUS_LOCK (message_handler);
290 old_free_func = handler->free_user_data;
291 old_user_data = handler->user_data;
293 handler->user_data = user_data;
294 handler->free_user_data = free_user_data;
295 _DBUS_UNLOCK (message_handler);
298 (* old_free_func) (old_user_data);
303 * Sets the handler function. Call dbus_message_handler_set_data()
304 * to set the user data for the function.
306 * @param handler the handler
307 * @param function the function
310 dbus_message_handler_set_function (DBusMessageHandler *handler,
311 DBusHandleMessageFunction function)
313 _dbus_return_if_fail (handler != NULL);
315 _DBUS_LOCK (message_handler);
316 handler->function = function;
317 _DBUS_UNLOCK (message_handler);