diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2008-03-13 22:27:22 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2008-03-13 22:27:22 +0000 |
commit | a89312e54979c0ee6cc82f50e423bcdafbe9df43 (patch) | |
tree | 5de94476be7e38742cc805e059342ed89d16be86 | |
parent | 095a8af653e9d5f7c2cf9c82c19f1281e8ad8b92 (diff) |
Added new function to remove the listener based on integer identification
-rw-r--r-- | common/dbus.c | 61 | ||||
-rw-r--r-- | common/dbus.h | 4 | ||||
-rw-r--r-- | hcid/adapter.c | 18 | ||||
-rw-r--r-- | hcid/adapter.h | 1 |
4 files changed, 71 insertions, 13 deletions
diff --git a/common/dbus.c b/common/dbus.c index 529caad3..e4008810 100644 --- a/common/dbus.c +++ b/common/dbus.c @@ -50,8 +50,7 @@ #define DISPATCH_TIMEOUT 0 -static int name_listener_initialized = 0; - +static guint listener_id = 0; static GSList *name_listeners = NULL; #ifndef HAVE_DBUS_GLIB @@ -81,6 +80,7 @@ struct disconnect_data { struct name_callback { name_cb_t func; void *user_data; + guint id; }; struct name_data { @@ -152,8 +152,8 @@ static void name_data_free(struct name_data *data) g_free(data); } -static int name_data_add(DBusConnection *connection, - const char *name, name_cb_t func, void *user_data) +static int name_data_add(DBusConnection *connection, const char *name, + name_cb_t func, void *user_data, guint id) { int first = 1; struct name_data *data = NULL; @@ -163,6 +163,7 @@ static int name_data_add(DBusConnection *connection, cb->func = func; cb->user_data = user_data; + cb->id = id; data = name_data_find(connection, name); if (data) { @@ -293,36 +294,36 @@ static DBusHandlerResult name_exit_filter(DBusConnection *connection, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -int name_listener_add(DBusConnection *connection, const char *name, +guint name_listener_add(DBusConnection *connection, const char *name, name_cb_t func, void *user_data) { int first; - if (!name_listener_initialized) { + if (!listener_id) { if (!dbus_connection_add_filter(connection, name_exit_filter, NULL, NULL)) { error("dbus_connection_add_filter() failed"); - return -1; + return 0; } - name_listener_initialized = 1; } - first = name_data_add(connection, name, func, user_data); + listener_id++; + first = name_data_add(connection, name, func, user_data, listener_id); /* The filter is already added if this is not the first callback * registration for the name */ if (!first) - return 0; + return listener_id; if (name) { debug("name_listener_add(%s)", name); if (!add_match(connection, name)) { name_data_remove(connection, name, func, user_data); - return -1; + return 0; } } - return 0; + return listener_id; } int name_listener_remove(DBusConnection *connection, const char *name, @@ -362,6 +363,42 @@ int name_listener_remove(DBusConnection *connection, const char *name, return 0; } +gboolean name_listener_id_remove(guint id) +{ + struct name_data *data; + struct name_callback *cb; + GSList *ldata, *lcb; + + for (ldata = name_listeners; ldata; ldata = ldata->next) { + data = ldata->data; + for (lcb = data->callbacks; lcb; lcb = lcb->next) { + cb = lcb->data; + if (cb->id == id) + goto remove; + } + } + + return FALSE; + +remove: + data->callbacks = g_slist_remove(data->callbacks, cb); + g_free(cb); + + /* Don't remove the filter if other callbacks exist */ + if (data->callbacks) + return TRUE; + + if (data->name) { + if (!remove_match(data->connection, data->name)) + return FALSE; + } + + name_listeners = g_slist_remove(name_listeners, data); + name_data_free(data); + + return TRUE; +} + int name_listener_indicate_disconnect(DBusConnection *connection) { struct name_data *data; diff --git a/common/dbus.h b/common/dbus.h index b65a83c9..b8223059 100644 --- a/common/dbus.h +++ b/common/dbus.h @@ -25,6 +25,7 @@ #define __H_BLUEZ_DBUS_H__ #include <dbus/dbus.h> +#include <glib.h> void setup_dbus_server_with_main_loop(DBusServer *server); void setup_dbus_with_main_loop(DBusConnection *conn); @@ -42,10 +43,11 @@ DBusHandlerResult simple_introspect(DBusConnection *conn, typedef void (*name_cb_t)(const char *name, void *user_data); -int name_listener_add(DBusConnection *connection, const char *name, +guint name_listener_add(DBusConnection *connection, const char *name, name_cb_t func, void *user_data); int name_listener_remove(DBusConnection *connection, const char *name, name_cb_t func, void *user_data); +gboolean name_listener_id_remove(guint id); int name_listener_indicate_disconnect(DBusConnection *connection); dbus_bool_t dbus_bus_get_unix_process_id(DBusConnection *conn, const char *name, diff --git a/hcid/adapter.c b/hcid/adapter.c index d46527d0..27ec1f4b 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -3343,6 +3343,12 @@ static void discover_services_cb(gpointer user_data, sdp_list_t *recs, int err) GSList *uuids; bdaddr_t src, dst; + /* Onwer exitted? */ + if (!adapter->create) { + sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + return; + } + if (err < 0) { error_connection_attempt_failed(adapter->create->conn, adapter->create->msg, -err); @@ -3410,6 +3416,15 @@ static void discover_services_cb(gpointer user_data, sdp_list_t *recs, int err) write_device_profiles(&src, &dst, ""); failed: + name_listener_id_remove(adapter->create->id); + dbus_connection_unref(adapter->create->conn); + dbus_message_unref(adapter->create->msg); + g_free(adapter->create); + adapter->create = NULL; +} + +static void create_device_exit(const char *name, struct adapter *adapter) +{ dbus_connection_unref(adapter->create->conn); dbus_message_unref(adapter->create->msg); g_free(adapter->create); @@ -3454,6 +3469,9 @@ static DBusHandlerResult create_device(DBusConnection *conn, create = g_new0(struct create_device_req, 1); create->conn = dbus_connection_ref(conn); create->msg = dbus_message_ref(msg); + create->id = name_listener_add(conn, + dbus_message_get_sender(msg), + (name_cb_t) create_device_exit, adapter); strcpy(create->address, address); adapter->create = create; diff --git a/hcid/adapter.h b/hcid/adapter.h index 9353fcdd..1943fbf2 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -84,6 +84,7 @@ struct create_device_req { char address[18]; /* Destination address */ DBusConnection *conn; /* Connection reference */ DBusMessage *msg; /* Message reference */ + guint id; /* Listener id */ }; struct adapter { |