summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorChengwei Yang <chengwei.yang@intel.com>2013-12-03 20:47:54 +0800
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-01-06 15:45:52 +0000
commit4e8032be4e6608163757b2ab926e44e5f784807d (patch)
tree030490c061ae31cbad26b1ec8c0c8b2be7b035fe /bus
parent653790c9858180baf4259b38c7c9d5196e39114b (diff)
downloaddbus-4e8032be4e6608163757b2ab926e44e5f784807d.tar.gz
Fix memory leak for kqueue: shutdown kqueue correctly
There are memory blocks leak when doing bus-test, both dispatch-sha1 and dispatch test cases complain memory blocks leak. This patch also fix fd leaks. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69332 Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Diffstat (limited to 'bus')
-rw-r--r--bus/dir-watch-kqueue.c87
1 files changed, 74 insertions, 13 deletions
diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c
index 065fabb3..4cc780de 100644
--- a/bus/dir-watch-kqueue.c
+++ b/bus/dir-watch-kqueue.c
@@ -87,11 +87,49 @@ _handle_kqueue_watch (DBusWatch *watch, unsigned int flags, void *data)
return TRUE;
}
+static void _shutdown_kqueue (void *data)
+{
+ int i;
+
+ if (kq < 0)
+ return;
+
+ for (i = 0; i < MAX_DIRS_TO_WATCH; i++)
+ {
+ if (fds[i] >= 0)
+ {
+ close (fds[i]);
+ fds[i] = -1;
+ }
+ if (dirs[i] != NULL)
+ {
+ /* dbus_free() is necessary to pass memleak check */
+ dbus_free (dirs[i]);
+ dirs[i] = NULL;
+ }
+ }
+
+ if (loop)
+ {
+ _dbus_loop_remove_watch (loop, watch);
+ _dbus_loop_unref (loop);
+ loop = NULL;
+ }
+
+ if (watch)
+ {
+ _dbus_watch_invalidate (watch);
+ _dbus_watch_unref (watch);
+ watch = NULL;
+ }
+
+ close (kq);
+ kq = -1;
+}
+
static int
_init_kqueue (BusContext *context)
{
- int ret = 0;
-
if (kq < 0)
{
@@ -103,6 +141,7 @@ _init_kqueue (BusContext *context)
}
loop = bus_context_get_loop (context);
+ _dbus_loop_ref (loop);
watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE,
_handle_kqueue_watch, NULL, NULL);
@@ -110,27 +149,49 @@ _init_kqueue (BusContext *context)
if (watch == NULL)
{
_dbus_warn ("Unable to create kqueue watch\n");
- close (kq);
- kq = -1;
- goto out;
+ goto out1;
}
if (!_dbus_loop_add_watch (loop, watch))
{
_dbus_warn ("Unable to add reload watch to main loop");
- _dbus_watch_invalidate (watch);
- _dbus_watch_unref (watch);
- watch = NULL;
- close (kq);
- kq = -1;
- goto out;
+ goto out2;
+ }
+
+ if (!_dbus_register_shutdown_func (_shutdown_kqueue, NULL))
+ {
+ _dbus_warn ("Unable to register shutdown function");
+ goto out3;
}
}
- ret = 1;
+ return 1;
+
+out3:
+ _dbus_loop_remove_watch (loop, watch);
+
+out2:
+ if (watch)
+ {
+ _dbus_watch_invalidate (watch);
+ _dbus_watch_unref (watch);
+ watch = NULL;
+ }
+
+out1:
+ if (kq >= 0)
+ {
+ close (kq);
+ kq = -1;
+ }
+ if (loop)
+ {
+ _dbus_loop_unref (loop);
+ loop = NULL;
+ }
out:
- return ret;
+ return 0;
}
void