summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 21:16:03 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 21:16:03 -0400
commit9da7c4a39b96be96fb5c0c34ef305c81151df898 (patch)
tree6356d6d8a42d8e3dc26e1ad7b1b09c43a3a4e2f7
parenta7e801c5ab9e6257011007a4ac08cd604843dd96 (diff)
Move lowlevel dbus stuff to dbus-int.c
-rw-r--r--dbus-int.c174
-rw-r--r--dbus.c445
-rw-r--r--libnul-private.h15
3 files changed, 223 insertions, 411 deletions
diff --git a/dbus-int.c b/dbus-int.c
index f398bd1..998b412 100644
--- a/dbus-int.c
+++ b/dbus-int.c
@@ -10,6 +10,7 @@ typedef struct object_info_t object_info_t;
struct object_info_t
{
char * name;
+ connection_t * connection;
message_func_t func;
gpointer data;
};
@@ -19,6 +20,8 @@ struct connection_t
DBusConnection *dconnection;
object_info_t **objects;
+
+ char ** names;
};
static void
@@ -302,6 +305,7 @@ ensure_connection (connection_t **connection,
conn = g_new0 (connection_t, 1);
conn->dconnection = dconn;
conn->objects = nul_array_new (object_info_t *);
+ conn->names = nul_array_new (char *);
*connection = conn;
}
@@ -337,22 +341,22 @@ connection_new_system (void)
}
static void
-unregister_connection (DBusConnection *connection,
- gpointer data)
+dbus_int_unregister_connection (DBusConnection *connection,
+ gpointer data)
{
/* nothing */
}
static DBusHandlerResult
-message_function (DBusConnection *connection,
- DBusMessage *message,
- gpointer data)
+dbus_int_message_function (DBusConnection *connection,
+ DBusMessage *message,
+ gpointer data)
{
object_info_t *info = data;
/* Parse the message into something sensible here */
- if (info->func ((void *)message, info->data))
+ if (info->func (info->connection, message, info->data))
return DBUS_HANDLER_RESULT_HANDLED;
else
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -360,8 +364,8 @@ message_function (DBusConnection *connection,
static const DBusObjectPathVTable vtable =
{
- unregister_connection,
- message_function,
+ dbus_int_unregister_connection,
+ dbus_int_message_function,
NULL,
};
@@ -372,6 +376,7 @@ connection_register_object (connection_t *connection,
nul_ptr_t data)
{
object_info_t *info = g_new0 (object_info_t, 1);
+ info->connection = connection;
info->name = g_strdup (object_name);
info->func = func;
info->data = data;
@@ -379,7 +384,7 @@ connection_register_object (connection_t *connection,
connection->objects = nul_array_append (connection->objects, info);
dbus_connection_register_object_path (
- connection->dconnection, object_name, &vtable, data);
+ connection->dconnection, object_name, &vtable, info);
}
void
@@ -404,3 +409,154 @@ connection_unregister_object (connection_t *connection,
}
}
}
+
+static gboolean
+owns_name (connection_t *connection,
+ const char *name)
+{
+ char **n;
+
+ for (n = connection->names; *n; n++)
+ {
+ if (strcmp (*n, name) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+connection_release_name (connection_t *connection,
+ const char * name)
+{
+ if (!owns_name (connection, name))
+ return;
+
+ /* FIXME: errors? */
+ dbus_bus_release_name (connection->dconnection, name, NULL);
+}
+
+gboolean
+connection_request_name (connection_t *connection,
+ const char *name)
+{
+ int r;
+ gboolean owner;
+
+ /* Possible flags:
+ *
+ * DBUS_NAME_FLAG_ALLOW_REPLACEMENT
+ * DBUS_NAME_FLAG_REPLACE_EXISTING
+ * DBUS_FLAG_DO_NOT_QUEUE
+ */
+
+ if (owns_name (connection, name))
+ return TRUE; /* Should we g_critical here? */
+
+ r = dbus_bus_request_name (connection->dconnection,
+ name, DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL);
+
+ owner = FALSE;
+
+ /* FIXME: errors */
+ if (r == -1)
+ {
+ return FALSE;
+ }
+ else
+ {
+ switch (r)
+ {
+ case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+ g_warning ("this should not happen according to dbus docs");
+ break;
+
+ case DBUS_REQUEST_NAME_REPLY_EXISTS:
+ break;
+
+ case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+ g_warning ("this should not happen");
+ owner = TRUE;
+ break;
+
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ owner = TRUE;
+ break;
+ }
+ }
+
+ if (owner)
+ {
+ connection->names = nul_array_append (
+ connection->names, g_strdup (name));
+ }
+
+ return owner;
+}
+
+typedef struct reply_info
+{
+ message_func_t func;
+ gpointer data;
+ connection_t *connection;
+} reply_info_t;
+
+static void
+dbus_int_handle_reply (DBusPendingCall *pending,
+ gpointer data)
+{
+ reply_info_t *info = data;
+ DBusMessage *reply;
+
+ if (!info->func)
+ return;
+
+ reply = dbus_pending_call_steal_reply (pending);
+
+ if (!reply)
+ {
+ /* FIXME: can this happen? */
+
+ return;
+ }
+
+ info->func (info->connection, reply, info->data);
+}
+
+gboolean
+connection_send_with_reply (connection_t *connection,
+ DBusMessage *message,
+ message_func_t func,
+ gpointer data)
+{
+ reply_info_t *info;
+ DBusPendingCall *pending;
+
+ dbus_connection_send_with_reply (
+ connection->dconnection, message, &pending, -1);
+
+ if (!pending)
+ {
+ /* FIXME: we should do something, not sure what */
+ return FALSE;
+ }
+ else
+ {
+ info = g_new0 (reply_info_t, 1);
+
+ info->func = func;
+ info->data = data;
+
+ dbus_pending_call_set_notify (
+ pending, dbus_int_handle_reply, info, g_free);
+
+ return TRUE;
+ }
+}
+
+void
+connection_send (connection_t *connection,
+ DBusMessage *message)
+{
+ connection_send_with_reply (connection, message, NULL, NULL);
+}
diff --git a/dbus.c b/dbus.c
index 32f63f6..6910120 100644
--- a/dbus.c
+++ b/dbus.c
@@ -21,6 +21,7 @@
#include <dbus/dbus.h>
#include <string.h>
#include "libnul.h"
+#include "libnul-private.h"
#define INTROSPECT_INTERFACE "org.freedesktop.DBus.Introspectable"
#define INTROSPECT_METHOD "Introspect"
@@ -29,7 +30,7 @@ struct nul_dbus_service_t
{
char *name;
nul_dbus_object_t **objects;
- DBusConnection *connection;
+ connection_t *connection;
gboolean running;
DBusBusType type;
};
@@ -85,218 +86,6 @@ struct nul_dbus_type_t
Primitive type;
};
-static void
-process_watch (DBusWatch *watch, int flags)
-{
- dbus_watch_handle (watch, flags);
-}
-
-static void
-on_hangup (gpointer data)
-{
- DBusWatch *watch = data;
-
- process_watch (watch, DBUS_WATCH_HANGUP);
-}
-
-static void
-on_error (gpointer data)
-{
- DBusWatch *watch = data;
-
- process_watch (watch, DBUS_WATCH_ERROR);
-}
-
-static void
-on_read (gpointer data)
-{
- GList *list = data;
-
- for (list = data; list != NULL; list = list->next)
- {
- DBusWatch *watch = list->data;
-
- if (dbus_watch_get_enabled (watch) &&
- (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE))
- {
- process_watch (watch, DBUS_WATCH_READABLE);
- }
- }
-}
-
-static void
-on_write (gpointer data)
-{
- GList *list = data;
-
- for (list = data; list != NULL; list = list->next)
- {
- DBusWatch *watch = list->data;
-
- if (dbus_watch_get_enabled (watch) &&
- (dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE))
- {
- process_watch (watch, DBUS_WATCH_WRITABLE);
- }
- }
-}
-
-static void
-update_fd (int fd)
-{
- int enabled, flags;
- GList *watches, *list;
-
- watches = nul_fd_get_data (fd);
-
- enabled = FALSE;
- flags = 0;
-
- for (list = watches; list != NULL; list = list->next)
- {
- DBusWatch *watch = list->data;
-
- if (dbus_watch_get_enabled (watch))
- {
- enabled = TRUE;
- flags |= dbus_watch_get_flags (watch);
- }
- }
-
- if (enabled)
- {
- nul_fd_set_error_callback (fd, on_hangup);
- nul_fd_set_hangup_callback (fd, on_error);
-
- if (flags & DBUS_WATCH_READABLE)
- nul_fd_set_read_callback (fd, on_read);
- else
- nul_fd_set_read_callback (fd, NULL);
-
- if (flags & DBUS_WATCH_WRITABLE)
- nul_fd_set_write_callback (fd, on_write);
- else
- nul_fd_set_write_callback (fd, NULL);
- }
- else
- {
- nul_fd_set_error_callback (fd, NULL);
- nul_fd_set_hangup_callback (fd, NULL);
- nul_fd_set_read_callback (fd, NULL);
- nul_fd_set_write_callback (fd, NULL);
- }
-}
-
-static dbus_bool_t
-add_watch (DBusWatch *watch, void *data)
-{
- DBusConnection *connection = data;
- int fd = dbus_watch_get_unix_fd (watch);
-
- dbus_watch_set_data (watch, connection, NULL);
-
- /* DBus apparently will create multiple watches for
- * the same fd.
- */
- if (nul_fd_is_watched (fd))
- {
- GList *watches = nul_fd_get_data (fd);
-
- watches = g_list_prepend (watches, watch);
-
- nul_fd_set_data (fd, watches);
- }
- else
- {
- nul_fd_add_watch (fd, g_list_prepend (NULL, watch));
- }
-
- update_fd (fd);
-
- return TRUE;
-}
-
-static void
-remove_watch (DBusWatch *watch, void *data)
-{
- int fd = dbus_watch_get_unix_fd (watch);
- GList *watches = nul_fd_get_data (fd);
-
- watches = g_list_remove (watches, watch);
-
- if (!watches)
- {
- nul_fd_remove_watch (fd);
- }
- else
- {
- nul_fd_set_data (fd, watches);
- update_fd (fd);
- }
-}
-
-static void
-toggle_watch (DBusWatch *watch, void *data)
-{
- update_fd (dbus_watch_get_unix_fd (watch));
-}
-
-static gboolean
-on_timeout (gpointer data)
-{
- DBusTimeout *timeout = data;
-
- dbus_timeout_handle (timeout);
-
- return TRUE;
-}
-
-static dbus_bool_t
-add_timeout (DBusTimeout *timeout, void *data)
-{
- dbus_timeout_set_data (timeout, GINT_TO_POINTER (0), NULL);
-
- if (dbus_timeout_get_enabled (timeout))
- {
- int id;
-
- id = g_timeout_add (dbus_timeout_get_interval (timeout),
- on_timeout, timeout);
-
- dbus_timeout_set_data (timeout, GINT_TO_POINTER (id), NULL);
- }
-
- return TRUE;
-}
-
-static void
-remove_timeout (DBusTimeout *timeout, void *data)
-{
- int id = GPOINTER_TO_INT (dbus_timeout_get_data (timeout));
-
- if (id)
- {
- g_source_remove (id);
-
- dbus_timeout_set_data (timeout, GINT_TO_POINTER (0), NULL);
- }
-}
-
-static void
-toggle_timeout (DBusTimeout *timeout, void *data)
-{
- remove_timeout (timeout, NULL);
-
- add_timeout (timeout, NULL);
-}
-
-static void
-unregister_connection (DBusConnection *connection,
- gpointer data)
-{
- /* nothing */
-}
-
typedef void (* nul_free_func_t) (nul_ptr_t p);
static nul_ptr_t *free_us;
@@ -548,7 +337,7 @@ encode_message (DBusMessage *message,
}
static DBusHandlerResult
-invoke (DBusConnection *connection,
+invoke (connection_t *connection,
nul_dbus_object_t *object,
nul_dbus_member_t *member,
DBusMessage *message)
@@ -578,7 +367,7 @@ invoke (DBusConnection *connection,
error_reply = dbus_message_new_error (
message, DBUS_ERROR_FAILED, "FIXME: generate a real error");
- dbus_connection_send (connection, error_reply, NULL);
+ connection_send (connection, error_reply);
result = DBUS_HANDLER_RESULT_HANDLED;
goto out;
@@ -609,7 +398,7 @@ invoke (DBusConnection *connection,
(nul_dbus_parameter_t **)&(member->parameters[member->n_inputs]),
&(args[member->n_inputs + 1]));
- dbus_connection_send (connection, reply, NULL);
+ connection_send (connection, reply);
dbus_message_unref (reply);
result = DBUS_HANDLER_RESULT_HANDLED;
@@ -625,8 +414,8 @@ out:
return result;
}
-static DBusHandlerResult
-message_function (DBusConnection *connection,
+static gboolean
+message_function (connection_t *connection,
DBusMessage *message,
gpointer data)
{
@@ -649,9 +438,9 @@ message_function (DBusConnection *connection,
DBUS_TYPE_STRING, &xml,
DBUS_TYPE_INVALID);
- dbus_connection_send (connection, reply, NULL);
+ connection_send (connection, reply);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return TRUE;
}
/* Normal method */
@@ -675,16 +464,9 @@ message_function (DBusConnection *connection,
g_print ("got unknown message\n");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ return FALSE;
}
-static const DBusObjectPathVTable vtable =
-{
- unregister_connection,
- message_function,
- NULL,
-};
-
static nul_ptr_t *
make_ptr_array (gpointer first, va_list parameters)
{
@@ -707,97 +489,9 @@ make_ptr_array (gpointer first, va_list parameters)
return array;
}
-static dbus_int32_t idle_id_slot = -1;
-
-static int
-get_idle_id (DBusConnection *connection)
-{
- if (idle_id_slot == -1)
- dbus_connection_allocate_data_slot (&idle_id_slot);
-
- return (int)dbus_connection_get_data (connection, idle_id_slot);
-}
-
-static void
-set_idle_id (DBusConnection *connection, int id)
-{
- if (idle_id_slot == -1)
- dbus_connection_allocate_data_slot (&idle_id_slot);
-
- dbus_connection_set_data (connection, idle_id_slot, (void *)id, NULL);
-}
-
-static gboolean
-do_dispatch (gpointer data)
-{
- DBusConnection *connection = data;
-
- while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS)
- ;
-
- set_idle_id (connection, 0);
-
- return FALSE;
-}
-
-static void
-on_dispatch_status_changed (DBusConnection *connection,
- DBusDispatchStatus new_status,
- void *data)
-{
- if (!get_idle_id (connection))
- set_idle_id (connection, g_idle_add (do_dispatch, connection));
-}
-
-static DBusConnection *
-ensure_connection (DBusConnection **connection,
- DBusBusType type,
- DBusError *err)
-{
- if (!*connection)
- {
- *connection = dbus_bus_get (type, err);
-
- if (*connection)
- {
- dbus_connection_set_dispatch_status_function (
- *connection,
- on_dispatch_status_changed, *connection, NULL);
-
- dbus_connection_set_watch_functions (
- *connection,
- add_watch, remove_watch, toggle_watch,
- *connection, NULL);
-
- dbus_connection_set_timeout_functions (
- *connection,
- add_timeout, remove_timeout, toggle_timeout,
- *connection, NULL);
- }
-
- do_dispatch (*connection);
- }
-
- return *connection;
-}
-
-static DBusConnection *
-get_connection (DBusBusType type, DBusError *err)
-{
- static DBusConnection *session_bus;
- static DBusConnection *system_bus;
-
- if (type == DBUS_BUS_SESSION)
- return ensure_connection (&session_bus, DBUS_BUS_SESSION, err);
- else if (type == DBUS_BUS_SYSTEM)
- return ensure_connection (&system_bus, DBUS_BUS_SYSTEM, err);
- else
- return NULL;
-}
-
static nul_dbus_service_t *
make_service (const char *name,
- DBusBusType type,
+ connection_t *connection,
nul_dbus_object_t *object1,
va_list args)
{
@@ -807,9 +501,7 @@ make_service (const char *name,
service->objects = (nul_dbus_object_t **)make_ptr_array (object1, args);
- service->type = type;
-
- service->connection = get_connection (type, NULL);
+ service->connection = connection;
if (!service->connection)
{
@@ -830,7 +522,7 @@ nul_dbus_session_service (const char *name,
va_start (args, object1);
- service = make_service (name, DBUS_BUS_SESSION, object1, args);
+ service = make_service (name, connection_new_session(), object1, args);
va_end (args);
@@ -840,62 +532,29 @@ nul_dbus_session_service (const char *name,
gboolean
nul_dbus_service_start (nul_dbus_service_t *service)
{
- DBusError err = DBUS_ERROR_INIT;
int i;
- int result;
if (service->running)
return FALSE;
- /* Possible flags:
- *
- * DBUS_NAME_FLAG_ALLOW_REPLACEMENT
- * DBUS_NAME_FLAG_REPLACE_EXISTING
- * DBUS_FLAG_DO_NOT_QUEUE
- */
- result = dbus_bus_request_name (service->connection,
- service->name,
- DBUS_NAME_FLAG_DO_NOT_QUEUE,
- &err);
-
- if (result == -1)
- {
- /* FIXME: handle error */
- return FALSE;
- }
-
- switch (result)
+ if (connection_request_name (service->connection,
+ service->name))
{
- case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
- g_assert_not_reached();
- break;
-
- case DBUS_REQUEST_NAME_REPLY_EXISTS:
- g_print ("Couldn't get name\n");
- return FALSE;
- break;
-
- case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
- g_print ("We own this already (?)\n");
- return FALSE;
- break;
-
- case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
- break;
- }
+ /* Register objects */
+ for (i = 0; service->objects[i] != NULL; ++i)
+ {
+ nul_dbus_object_t *object = service->objects[i];
+
+ connection_register_object (
+ service->connection, object->name, message_function, object);
+ }
- /* Register objects */
- for (i = 0; service->objects[i] != NULL; ++i)
- {
- nul_dbus_object_t *object = service->objects[i];
-
- dbus_connection_register_object_path (
- service->connection, object->name, &vtable, object);
+ service->running = TRUE;
+
+ return TRUE;
}
- service->running = TRUE;
-
- return TRUE;
+ return FALSE;
}
void
@@ -909,12 +568,12 @@ nul_dbus_service_stop (nul_dbus_service_t *service)
for (obj = service->objects; *obj != NULL; ++obj)
{
nul_dbus_object_t *object = *obj;
-
- dbus_connection_unregister_object_path (
+
+ connection_unregister_object (
service->connection, object->name);
}
- dbus_bus_release_name (service->connection, service->name, NULL);
+ connection_release_name (service->connection, service->name);
service->running = FALSE;
}
@@ -1168,30 +827,20 @@ typedef struct
nul_dbus_member_t *method;
} InvokeInfo;
-static void
-on_reply (DBusPendingCall *pending,
+static gboolean
+on_reply (connection_t *connection,
+ DBusMessage *reply,
gpointer data)
{
InvokeInfo *info = data;
int n_outputs = info->method->n_outputs;
nul_dbus_parameter_t **outputs;
- DBusMessage *reply;
nul_arg_t *args;
nul_arg_t arg;
char *err;
if (!info->callback)
- return;
-
- reply = dbus_pending_call_steal_reply (pending);
-
- if (!reply)
- {
- /* FIXME: can this happen? If it can, we should
- * generate an error.
- */
- return;
- }
+ return TRUE;
outputs = (nul_dbus_parameter_t **)&(info->method->parameters[info->method->n_inputs]);
@@ -1209,6 +858,8 @@ on_reply (DBusPendingCall *pending,
nul_fun_def_invoke (info->method->reply_fun, (nul_function_t)info->callback, args);
nul_array_free (args);
+
+ return TRUE;
}
/* Decodes strings like this:
@@ -1301,10 +952,9 @@ nul_dbus_invoke (nul_dbus_service_t *service,
nul_dbus_member_t *method;
DBusMessage *message;
DBusMessageIter iter;
- DBusConnection *connection;
+ connection_t *connection;
va_list args;
InvokeInfo *info;
- DBusPendingCall *pending;
nul_dbus_parameter_t **p;
g_return_if_fail (service != NULL);
@@ -1377,10 +1027,15 @@ nul_dbus_invoke (nul_dbus_service_t *service,
va_end (args);
- connection = get_connection (service->type, NULL);
+ connection = service->connection;
+
+ info = g_new0 (InvokeInfo, 1);
+
+ info->callback = callback;
+ info->data = data;
+ info->method = method;
- dbus_connection_send_with_reply (connection, message, &pending, -1);
- if (!pending)
+ if (!connection_send_with_reply (connection, message, on_reply, info))
{
/* FIXME: generate an error and call the callback */
@@ -1388,16 +1043,6 @@ nul_dbus_invoke (nul_dbus_service_t *service,
* though it's not clear what we should do with that
*/
}
- else
- {
- info = g_new0 (InvokeInfo, 1);
-
- info->callback = callback;
- info->data = data;
- info->method = method;
-
- dbus_pending_call_set_notify (pending, on_reply, info, g_free);
- }
dbus_message_unref (message);
}
diff --git a/libnul-private.h b/libnul-private.h
index df7cf3e..a055b03 100644
--- a/libnul-private.h
+++ b/libnul-private.h
@@ -2,8 +2,9 @@
typedef struct connection_t connection_t;
typedef struct message_t message_t;
-typedef gboolean (* message_func_t) (DBusMessage *message,
- nul_ptr_t data);
+typedef gboolean (* message_func_t) (connection_t *connection,
+ DBusMessage *message,
+ nul_ptr_t data);
connection_t *connection_new_session (void);
connection_t *connection_new_system (void);
@@ -13,3 +14,13 @@ void connection_register_object (connection_t *connection,
nul_ptr_t data);
void connection_unregister_object (connection_t *connection,
const char *object_name);
+gboolean connection_request_name (connection_t *connection,
+ const char *name);
+void connection_send (connection_t *connection,
+ DBusMessage *message);
+gboolean connection_send_with_reply (connection_t *connection,
+ DBusMessage *message,
+ message_func_t func,
+ gpointer data);
+void connection_release_name (connection_t *connection,
+ const char * name);