summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2008-03-13 22:27:22 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2008-03-13 22:27:22 +0000
commita89312e54979c0ee6cc82f50e423bcdafbe9df43 (patch)
tree5de94476be7e38742cc805e059342ed89d16be86
parent095a8af653e9d5f7c2cf9c82c19f1281e8ad8b92 (diff)
Added new function to remove the listener based on integer identification
-rw-r--r--common/dbus.c61
-rw-r--r--common/dbus.h4
-rw-r--r--hcid/adapter.c18
-rw-r--r--hcid/adapter.h1
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 {