diff options
Diffstat (limited to 'bus/dir-watch-kqueue.c')
-rw-r--r-- | bus/dir-watch-kqueue.c | 175 |
1 files changed, 118 insertions, 57 deletions
diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c index ac6290cc..33d5e95d 100644 --- a/bus/dir-watch-kqueue.c +++ b/bus/dir-watch-kqueue.c @@ -73,12 +73,12 @@ _handle_kqueue_watch (DBusWatch *watch, unsigned int flags, void *data) { kq = -1; if (watch != NULL) - { - _dbus_loop_remove_watch (loop, watch); + { + _dbus_loop_remove_watch (loop, watch); _dbus_watch_invalidate (watch); _dbus_watch_unref (watch); - watch = NULL; - } + watch = NULL; + } pid = getpid (); _dbus_verbose ("Sending SIGHUP signal since kqueue has been closed\n"); (void) kill (pid, SIGHUP); @@ -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) { @@ -99,38 +137,61 @@ _init_kqueue (BusContext *context) if (kq < 0) { _dbus_warn ("Cannot create kqueue; error '%s'\n", _dbus_strerror (errno)); - goto out; - } - - loop = bus_context_get_loop (context); - - watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE, - _handle_kqueue_watch, NULL, NULL); - - if (watch == NULL) - { - _dbus_warn ("Unable to create kqueue watch\n"); - close (kq); - kq = -1; - goto out; - } - - 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 out; + } + + loop = bus_context_get_loop (context); + _dbus_loop_ref (loop); + + watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE, + _handle_kqueue_watch, NULL, NULL); + + if (watch == NULL) + { + _dbus_warn ("Unable to create kqueue watch\n"); + goto out1; + } + + if (!_dbus_loop_add_watch (loop, watch)) + { + _dbus_warn ("Unable to add reload watch to main loop"); + goto out2; + } + + if (!_dbus_register_shutdown_func (_shutdown_kqueue, NULL)) + { + _dbus_warn ("Unable to register shutdown function"); + goto out3; + } + } + + return 1; + +out3: + _dbus_loop_remove_watch (loop, watch); + +out2: + if (watch) + { + _dbus_watch_invalidate (watch); + _dbus_watch_unref (watch); + watch = NULL; } - ret = 1; +out1: + if (kq >= 0) + { + close (kq); + kq = -1; + } + if (loop) + { + _dbus_loop_unref (loop); + loop = NULL; + } out: - return ret; + return 0; } void @@ -139,7 +200,7 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories) int new_fds[MAX_DIRS_TO_WATCH]; char *new_dirs[MAX_DIRS_TO_WATCH]; DBusList *link; - int i, j, f, fd; + int i, j, fd; struct kevent ev; if (!_init_kqueue (context)) @@ -169,12 +230,12 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories) if (dirs[j] && strcmp (new_dirs[i], dirs[j]) == 0) { new_fds[i] = fds[j]; - new_dirs[i] = dirs[j]; - fds[j] = -1; - dirs[j] = NULL; - break; - } - } + new_dirs[i] = dirs[j]; + fds[j] = -1; + dirs[j] = NULL; + break; + } + } } /* Any directory we find in "fds" with a nonzero fd must @@ -185,10 +246,10 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories) if (fds[j] != -1) { close (fds[j]); - dbus_free (dirs[j]); - fds[j] = -1; - dirs[j] = NULL; - } + dbus_free (dirs[j]); + fds[j] = -1; + dirs[j] = NULL; + } } for (i = 0; new_dirs[i]; i++) @@ -196,9 +257,9 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories) if (new_fds[i] == -1) { /* FIXME - less lame error handling for failing to add a watch; - * we may need to sleep. - */ - fd = open (new_dirs[i], O_RDONLY); + * we may need to sleep. + */ + fd = open (new_dirs[i], O_RDONLY | O_CLOEXEC); if (fd < 0) { if (errno != ENOENT) @@ -223,18 +284,18 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories) goto out; } - new_fds[i] = fd; - new_dirs[i] = _dbus_strdup (new_dirs[i]); - if (!new_dirs[i]) + new_fds[i] = fd; + new_dirs[i] = _dbus_strdup (new_dirs[i]); + if (!new_dirs[i]) { /* FIXME have less lame handling for OOM, we just silently fail to - * watch. (In reality though, the whole OOM handling in dbus is - * stupid but we won't go into that in this comment =) ) - */ + * watch. (In reality though, the whole OOM handling in dbus is + * stupid but we won't go into that in this comment =) ) + */ close (fd); - new_fds[i] = -1; - } - } + new_fds[i] = -1; + } + } } num_fds = i; |