From 4af62affe9d74c45ec56f78ca83786c252fcac3f Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Sun, 1 Dec 2013 20:59:36 +0800 Subject: [PATCH 2/3] Fix memory leak for kqueue: shutdown kqueue correctly There are two blocks leaks when do bus-test dispatch-sha1, this patch fix one about the watch leaks. Also, it fixes other memory leaks, though they're not reported in test case because they were not reqested from dbus_malloc[0]. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69332 --- bus/dir-watch-kqueue.c | 89 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c index 065fabb..cd55a0a 100644 --- a/bus/dir-watch-kqueue.c +++ b/bus/dir-watch-kqueue.c @@ -87,11 +87,51 @@ _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) + { + 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; + } + + if (kq >= 0) + { + close (kq); + kq = -1; + } +} + static int _init_kqueue (BusContext *context) { - int ret = 0; - if (kq < 0) { @@ -103,6 +143,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 +151,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 -- 1.7.9.5