[PATCH 3/3] Fix memory leaks in btio/btio.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The watches created by bt_io_* functions were not being removed from
main context, therefore the "destroy" function was never being called.
---
 btio/btio.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 btio/btio.h |    2 ++
 src/main.c  |    3 +++
 3 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/btio/btio.c b/btio/btio.c
index d8439e0..0cd046e 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -65,12 +65,14 @@ struct connect {
 	BtIOConnect connect;
 	gpointer user_data;
 	GDestroyNotify destroy;
+	guint watch_id;
 };
 
 struct accept {
 	BtIOConnect connect;
 	gpointer user_data;
 	GDestroyNotify destroy;
+	guint watch_id;
 };
 
 struct server {
@@ -78,8 +80,11 @@ struct server {
 	BtIOConfirm confirm;
 	gpointer user_data;
 	GDestroyNotify destroy;
+	guint watch_id;
 };
 
+static GSList *servers = NULL, *accepts = NULL, *connects = NULL;
+
 static void server_remove(struct server *server)
 {
 	if (server->destroy)
@@ -215,8 +220,11 @@ static void server_add(GIOChannel *io, BtIOConnect connect,
 	server->destroy = destroy;
 
 	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, server_cb, server,
-					(GDestroyNotify) server_remove);
+	server->watch_id = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond,
+						server_cb, server,
+						(GDestroyNotify) server_remove);
+
+	servers = g_slist_append(servers, server);
 }
 
 static void connect_add(GIOChannel *io, BtIOConnect connect,
@@ -231,8 +239,11 @@ static void connect_add(GIOChannel *io, BtIOConnect connect,
 	conn->destroy = destroy;
 
 	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, connect_cb, conn,
+	conn->watch_id = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond,
+					connect_cb, conn,
 					(GDestroyNotify) connect_remove);
+
+	connects = g_slist_append(connects, conn);
 }
 
 static void accept_add(GIOChannel *io, BtIOConnect connect, gpointer user_data,
@@ -247,8 +258,11 @@ static void accept_add(GIOChannel *io, BtIOConnect connect, gpointer user_data,
 	accept->destroy = destroy;
 
 	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, accept_cb, accept,
-					(GDestroyNotify) accept_remove);
+	accept->watch_id = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond,
+						accept_cb, accept,
+						(GDestroyNotify) accept_remove);
+
+	accepts = g_slist_append(accepts, accept);
 }
 
 static int l2cap_bind(int sock, const bdaddr_t *src, uint16_t psm,
@@ -1313,6 +1327,38 @@ GIOChannel *bt_io_listen(BtIOType type, BtIOConnect connect,
 	return io;
 }
 
+void bt_io_destroy(void)
+{
+	GSList *l;
+
+	for (l = servers; l != NULL; l = g_slist_next(l)) {
+		struct server *server = l->data;
+
+		if (server->watch_id > 0)
+			g_source_remove(server->watch_id);
+	}
+	g_slist_free(servers);
+	servers = NULL;
+
+	for (l = connects; l != NULL; l = g_slist_next(l)) {
+		struct connect *conn = l->data;
+
+		if (conn->watch_id > 0)
+			g_source_remove(conn->watch_id);
+	}
+	g_slist_free(connects);
+	connects = NULL;
+
+	for (l = connects; l != NULL; l = g_slist_next(l)) {
+		struct accept *accept = l->data;
+
+		if (accept->watch_id > 0)
+			g_source_remove(accept->watch_id);
+	}
+	g_slist_free(accepts);
+	accepts = NULL;
+}
+
 GQuark bt_io_error_quark(void)
 {
 	return g_quark_from_static_string("bt-io-error-quark");
diff --git a/btio/btio.h b/btio/btio.h
index 53e8eaa..87e722f 100644
--- a/btio/btio.h
+++ b/btio/btio.h
@@ -95,4 +95,6 @@ GIOChannel *bt_io_listen(BtIOType type, BtIOConnect connect,
 				GDestroyNotify destroy, GError **err,
 				BtIOOption opt1, ...);
 
+void bt_io_destroy(void);
+
 #endif
diff --git a/src/main.c b/src/main.c
index 1aaa181..1b7ff40 100644
--- a/src/main.c
+++ b/src/main.c
@@ -56,6 +56,7 @@
 #include "dbus-common.h"
 #include "agent.h"
 #include "manager.h"
+#include "btio.h"
 
 #ifdef HAVE_CAPNG
 #include <cap-ng.h>
@@ -495,6 +496,8 @@ int main(int argc, char *argv[])
 
 	agent_exit();
 
+	bt_io_destroy();
+
 	g_main_loop_unref(event_loop);
 
 	if (config)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux