diff options
| -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 { | 
