diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-27 08:48:53 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-27 08:48:53 +0200 |
commit | c998f0a36783f32bb6b804b3d642bc1a5fde2563 (patch) | |
tree | 97d55e646c9c50a8443d1e51e47dc8661b98a69f /src/sdpd-server.c | |
parent | 0b85d06d59441cb294d6ca3a736b76629d820743 (diff) | |
download | bluez-c998f0a36783f32bb6b804b3d642bc1a5fde2563.tar.gz |
Fix closing of SDP server sockets
The existing code relied on set_close_on_unref which doesn't work as
long as the io watch callbacks hold on to their own reference. To fix
this it's better to track the watch id's instead of the IO channels and
do g_source_remove instead of g_io_channel_unref.
This isn't a particularly critical fd leak since these are created once
on bluetoothd startup and closed on exit, however they do help clean up
the valgrind fd-leak report.
Diffstat (limited to 'src/sdpd-server.c')
-rw-r--r-- | src/sdpd-server.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/sdpd-server.c b/src/sdpd-server.c index efd6fd0b1..a92ae2cd5 100644 --- a/src/sdpd-server.c +++ b/src/sdpd-server.c @@ -48,7 +48,7 @@ #include "log.h" #include "sdpd.h" -static GIOChannel *l2cap_io = NULL, *unix_io = NULL; +static guint l2cap_id = 0, unix_id = 0; static int l2cap_sock, unix_sock; @@ -195,10 +195,8 @@ static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer da GIOChannel *io; int nsk; - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { - g_io_channel_unref(chan); + if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) return FALSE; - } if (data == &l2cap_sock) { struct sockaddr_l2 addr; @@ -233,6 +231,7 @@ int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags) { int compat = flags & SDP_SERVER_COMPAT; int master = flags & SDP_SERVER_MASTER; + GIOChannel *io; info("Starting SDP server"); @@ -256,18 +255,21 @@ int start_sdp_server(uint16_t mtu, const char *did, uint32_t flags) } } - l2cap_io = g_io_channel_unix_new(l2cap_sock); - g_io_channel_set_close_on_unref(l2cap_io, TRUE); + io = g_io_channel_unix_new(l2cap_sock); + g_io_channel_set_close_on_unref(io, TRUE); - g_io_add_watch(l2cap_io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + l2cap_id = g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, io_accept_event, &l2cap_sock); + g_io_channel_unref(io); if (compat && unix_sock > fileno(stderr)) { - unix_io = g_io_channel_unix_new(unix_sock); - g_io_channel_set_close_on_unref(unix_io, TRUE); + io = g_io_channel_unix_new(unix_sock); + g_io_channel_set_close_on_unref(io, TRUE); - g_io_add_watch(unix_io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + unix_id = g_io_add_watch(io, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, io_accept_event, &unix_sock); + g_io_channel_unref(io); } return 0; @@ -279,9 +281,12 @@ void stop_sdp_server(void) sdp_svcdb_reset(); - if (unix_io) - g_io_channel_unref(unix_io); + if (unix_id > 0) + g_source_remove(unix_id); + + if (l2cap_id > 0) + g_source_remove(l2cap_id); - if (l2cap_io) - g_io_channel_unref(l2cap_io); + l2cap_id = unix_id = 0; + l2cap_sock = unix_sock = -1; } |