From 89efba8e355d3fe82db11eefbc2b4723334c6c60 Mon Sep 17 00:00:00 2001 From: barbieri Date: Sat, 11 Oct 2008 07:11:42 +0000 Subject: [PATCH] e_dbus: better error and reference handling. This patch does a refactor of e_dbus_methods and e_dbus_interfaces so these methods return a pending call that can be canceled. It will also print out possible errors and will unref the message after usage. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/e_dbus@36579 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/dbus/E_DBus.h | 80 +++++++++++------------ src/lib/dbus/e_dbus_interfaces.c | 114 +++++++++++++++++++++++++------- src/lib/dbus/e_dbus_message.c | 9 ++- src/lib/dbus/e_dbus_methods.c | 138 +++++++++++++++++++++++++++------------ 4 files changed, 230 insertions(+), 111 deletions(-) diff --git a/src/lib/dbus/E_DBus.h b/src/lib/dbus/E_DBus.h index e08246f..631a057 100644 --- a/src/lib/dbus/E_DBus.h +++ b/src/lib/dbus/E_DBus.h @@ -104,48 +104,48 @@ extern "C" { /* standard dbus method calls */ - EAPI void e_dbus_request_name(E_DBus_Connection *conn, const char *name, - unsigned int flags, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_release_name(E_DBus_Connection *conn, const char *name, - E_DBus_Method_Return_Cb cb_return, - void *data); - - EAPI void e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_list_names(E_DBus_Connection *conn, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_list_activatable_names(E_DBus_Connection *conn, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, - E_DBus_Method_Return_Cb cb_return, - void *data); + EAPI DBusPendingCall *e_dbus_request_name(E_DBus_Connection *conn, const char *name, + unsigned int flags, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_release_name(E_DBus_Connection *conn, const char *name, + E_DBus_Method_Return_Cb cb_return, + const void *data); + + EAPI DBusPendingCall *e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_list_names(E_DBus_Connection *conn, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_list_activatable_names(E_DBus_Connection *conn, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, + E_DBus_Method_Return_Cb cb_return, + const void *data); /* standard methods calls on objects */ - EAPI void e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination, - const char *path, E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_peer_get_machine_id(E_DBus_Connection *conn, - const char *destination, const char *path, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_properties_get(E_DBus_Connection *conn, const char *destination, - const char *path, const char *interface, - const char *property, - E_DBus_Method_Return_Cb cb_return, - void *data); - EAPI void e_dbus_properties_set(E_DBus_Connection *conn, const char *destination, - const char *path, const char *interface, - const char *property, int value_type, - void *value, E_DBus_Method_Return_Cb cb_return, - void *data); + EAPI DBusPendingCall *e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination, + const char *path, E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_peer_get_machine_id(E_DBus_Connection *conn, + const char *destination, const char *path, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_properties_get(E_DBus_Connection *conn, const char *destination, + const char *path, const char *interface, + const char *property, + E_DBus_Method_Return_Cb cb_return, + const void *data); + EAPI DBusPendingCall *e_dbus_properties_set(E_DBus_Connection *conn, const char *destination, + const char *path, const char *interface, + const char *property, int value_type, + const void *value, E_DBus_Method_Return_Cb cb_return, + const void *data); EAPI E_DBus_Callback *e_dbus_callback_new(E_DBus_Callback_Func cb_func, E_DBus_Unmarshal_Func unmarshal_func, E_DBus_Free_Func free_func, void *user_data); diff --git a/src/lib/dbus/e_dbus_interfaces.c b/src/lib/dbus/e_dbus_interfaces.c index 772543b..df0dffa 100644 --- a/src/lib/dbus/e_dbus_interfaces.c +++ b/src/lib/dbus/e_dbus_interfaces.c @@ -6,6 +6,33 @@ * objects on the bus should implement. */ +static inline DBusPendingCall * +_dbus_peer_call(E_DBus_Connection *conn, const char *method_name, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data) +{ + DBusMessage *msg; + DBusPendingCall *ret; + + msg = dbus_message_new_method_call + (destination, path, "org.freedesktop.DBus.Peer", method_name); + if (!msg) + { + fprintf(stderr, + "ERROR: failed to create message for method call: %s() at " + "\"%s\" at \"%s\"\n", + method_name, destination, path); + return NULL; + } + + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); + + if (!ret) + fprintf(stderr, "ERROR: could not %s() \"%s\" at \"%s\".\n", + method_name, destination, path); + + return ret; +} + /** * Ping the dbus peer * @@ -15,13 +42,10 @@ * @param cb_return a callback for a successful return * @param data data to pass to the callbacks */ -EAPI void -e_dbus_peer_ping(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data) { - DBusMessage *msg; - - msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Peer", "Ping"); - e_dbus_message_send(conn, msg, cb_return, -1, data); + return _dbus_peer_call(conn, "Ping", destination, path, cb_return, data); } /** @@ -33,13 +57,37 @@ e_dbus_peer_ping(E_DBus_Connection*conn, const char *destination, const char *pa * @param cb_return a callback for a successful return * @param data data to pass to the callbacks */ -EAPI void -e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data) +{ + return _dbus_peer_call(conn, "GetMachineId", destination, path, cb_return, data); +} + +static inline DBusMessage * +_dbus_message_property_method_call(E_DBus_Connection *conn, const char *method_name, const char *destination, const char *path, const char *interface, const char *property) { DBusMessage *msg; - msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Peer", "GetMachineId"); - e_dbus_message_send(conn, msg, cb_return, -1, data); + if (!conn) + { + fprintf(stderr, "ERROR: no connection for call of %s\n", method_name); + return NULL; + } + + msg = dbus_message_new_method_call + (destination, path, "org.freedesktop.DBus.Properties", method_name); + if (!msg) + { + fprintf(stderr, + "ERROR: failed to create message for method call: %s() at " + "\"%s\" at \"%s\"\n", + method_name, destination, path); + return NULL; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); + return msg; } /** @@ -53,14 +101,24 @@ e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, cons * @param cb_return a callback for a successful return * @param data data to pass to the callbacks */ -EAPI void -e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, E_DBus_Method_Return_Cb cb_return, const void *data) { DBusMessage *msg; + DBusPendingCall *ret; + + msg = _dbus_message_property_method_call + (conn, "Get", destination, path, interface, property); + if (!msg) + return NULL; + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); - msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Properties", "Get"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); + if (!ret) + fprintf(stderr, "ERROR: failed to call Get() at \"%s\" at \"%s\"\n", + destination, path); + + return ret; } /** @@ -76,32 +134,42 @@ e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const cha * @param cb_return a callback for a successful return * @param data data to pass to the callbacks */ -EAPI void -e_dbus_properties_set(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, int value_type, void *value, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_properties_set(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, int value_type, const void *value, E_DBus_Method_Return_Cb cb_return, const void *data) { DBusMessage *msg; DBusMessageIter iter, sub; DBusError err; + DBusPendingCall *ret; - if (!dbus_type_is_basic(value_type)) + if (!dbus_type_is_basic(value_type)) { if (cb_return) { dbus_error_init(&err); dbus_set_error(&err, "org.enlightenment.DBus.InvalidType", "Only basic types may be set using e_dbus_properties_set()"); - cb_return(data, NULL, &err); + cb_return((void *)data, NULL, &err); } - return; + return NULL; } - msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Properties", "Set"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID); + msg = _dbus_message_property_method_call + (conn, "Set", destination, path, interface, property); + if (!msg) + return NULL; dbus_message_iter_init_append(msg, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, dbus_message_type_to_string(value_type), &sub); dbus_message_iter_append_basic(&sub, value_type, &value); dbus_message_iter_close_container(&iter, &sub); - e_dbus_message_send(conn, msg, cb_return, -1, data); + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); + + if (!ret) + fprintf(stderr, "ERROR: failed to call Set() at \"%s\" at \"%s\"\n", + destination, path); + + return ret; } diff --git a/src/lib/dbus/e_dbus_message.c b/src/lib/dbus/e_dbus_message.c index 68bfc47..b77aa9f 100644 --- a/src/lib/dbus/e_dbus_message.c +++ b/src/lib/dbus/e_dbus_message.c @@ -5,8 +5,6 @@ typedef struct E_DBus_Pending_Call_Data E_DBus_Pending_Call_Data; struct E_DBus_Pending_Call_Data { - int serial; - E_DBus_Method_Return_Cb cb_return; void *data; }; @@ -70,15 +68,16 @@ e_dbus_message_send(E_DBus_Connection *conn, DBusMessage *msg, E_DBus_Method_Ret if (!dbus_connection_send_with_reply(conn->conn, msg, &pending, timeout)) return NULL; - if (cb_return) + if (cb_return && pending) { E_DBus_Pending_Call_Data *pdata; - pdata = calloc(1, sizeof(E_DBus_Pending_Call_Data)); + pdata = malloc(sizeof(E_DBus_Pending_Call_Data)); pdata->cb_return = cb_return; pdata->data = data; - dbus_pending_call_set_notify(pending, cb_pending, pdata, free); + if (!dbus_pending_call_set_notify(pending, cb_pending, pdata, free)) + free(pdata); } return pending; diff --git a/src/lib/dbus/e_dbus_methods.c b/src/lib/dbus/e_dbus_methods.c index 1b3b71f..a3f70e2 100644 --- a/src/lib/dbus/e_dbus_methods.c +++ b/src/lib/dbus/e_dbus_methods.c @@ -1,76 +1,128 @@ #include "E_DBus.h" #include "e_dbus_private.h" -EAPI void -e_dbus_request_name(E_DBus_Connection *conn, const char *name, unsigned int flags, E_DBus_Method_Return_Cb cb_return, void *data) +static inline DBusMessage * +_dbus_message_method_call(const char *method_name) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_call + ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + method_name); + if (!msg) + fprintf(stderr, "ERROR: failed to create message for method call: %s\n", + method_name); + return msg; +} + +static inline DBusPendingCall * +_dbus_call__void(E_DBus_Connection *conn, const const char *method_name, E_DBus_Method_Return_Cb cb_return, const void *data) { DBusMessage *msg; - dbus_uint32_t u_flags; + DBusPendingCall *ret; + + if (!conn) + { + fprintf(stderr, "ERROR: no connection for call of %s\n", method_name); + return NULL; + } + + msg = _dbus_message_method_call(method_name); + if (!msg) + return NULL; + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); - u_flags = flags; + if (!ret) + fprintf(stderr, "ERROR: failed to call %s()\n", method_name); - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &u_flags, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); + return ret; } -EAPI void -e_dbus_release_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data) +static inline DBusPendingCall * +_dbus_call__str(E_DBus_Connection *conn, const const char *method_name, const char *str, E_DBus_Method_Return_Cb cb_return, const void *data) { DBusMessage *msg; + DBusPendingCall *ret; - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ReleaseName"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); -} + if (!conn) + { + fprintf(stderr, "ERROR: no connection for call of %s\n", method_name); + return NULL; + } + msg = _dbus_message_method_call(method_name); + if (!msg) + return NULL; + dbus_message_append_args(msg, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); -EAPI void -e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data) -{ - DBusMessage *msg; + if (!ret) + fprintf(stderr, "ERROR: failed to call %s(\"%s\")\n", method_name, str); - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetNameOwner"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); + return ret; } -EAPI void -e_dbus_list_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_request_name(E_DBus_Connection *conn, const char *name, unsigned int flags, E_DBus_Method_Return_Cb cb_return, const void *data) { - DBusMessage *msg; + DBusPendingCall *ret; + DBusMessage *msg; + dbus_uint32_t u_flags; + + if (!conn) + { + fputs("ERROR: no connection for call of RequestName\n", stderr); + return NULL; + } + + u_flags = flags; + + msg = _dbus_message_method_call("RequestName"); + if (!msg) + return NULL; + dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &u_flags, DBUS_TYPE_INVALID); + ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data); + dbus_message_unref(msg); + return ret; +} - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames"); - e_dbus_message_send(conn, msg, cb_return, -1, data); +EAPI DBusPendingCall * +e_dbus_release_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data) +{ + return _dbus_call__str(conn, "ReleaseName", name, cb_return, data); } -EAPI void -e_dbus_list_activatable_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data) { - DBusMessage *msg; + return _dbus_call__str(conn, "GetNameOwner", name, cb_return, data); +} - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListActivatableNames"); - e_dbus_message_send(conn, msg, cb_return, -1, data); +EAPI DBusPendingCall * +e_dbus_list_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, const void *data) +{ + return _dbus_call__void(conn, "ListNames", cb_return, data); } -EAPI void -e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data) + +EAPI DBusPendingCall * +e_dbus_list_activatable_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, const void *data) { - DBusMessage *msg; + return _dbus_call__void(conn, "ListActivatableNames", cb_return, data); +} - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameHasOwner"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); +EAPI DBusPendingCall * +e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data) +{ + return _dbus_call__str(conn, "NameHasOwner", name, cb_return, data); } -EAPI void -e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data) +EAPI DBusPendingCall * +e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data) { - DBusMessage *msg; - - msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "StartServiceByName"); - dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); - e_dbus_message_send(conn, msg, cb_return, -1, data); + return _dbus_call__str(conn, "StartServiceByName", name, cb_return, data); } -- 2.7.4