summaryrefslogtreecommitdiff
path: root/gio/inotify
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-07-25 10:28:42 -0400
committerMatthias Clasen <mclasen@redhat.com>2013-07-28 17:19:38 -0400
commitabbb22573813405215c11bff9fb6b110880fd711 (patch)
tree1dae47351c507b93313b8a3f3a8a7af382d96a71 /gio/inotify
parent5843582604c9b1b0d459dc7f15182c966d112d9e (diff)
downloadglib-abbb22573813405215c11bff9fb6b110880fd711.tar.gz
inotify: don't assume mainloop is running
GFileMonitor takes great care to sample the thread-default main context at the time that it is created in order that events can be dispatched to the correct thread when they come in. The inotify GFileMonitor implementation uses a global file descriptor shared between all watches. It has to poll this file descriptor from somewhere so it arbitrarily picks the default main context. The problem with that is that the user might not be running it. Let's use the GLib worker thread for this instead. It's guaranteed to be running if you need it, and this is exactly the sort of problem it was meant to solve. https://bugzilla.gnome.org/show_bug.cgi?id=704873
Diffstat (limited to 'gio/inotify')
-rw-r--r--gio/inotify/inotify-kernel.c20
-rw-r--r--gio/inotify/inotify-missing.c8
2 files changed, 23 insertions, 5 deletions
diff --git a/gio/inotify/inotify-kernel.c b/gio/inotify/inotify-kernel.c
index 4ffddb433..d59dc23cd 100644
--- a/gio/inotify/inotify-kernel.c
+++ b/gio/inotify/inotify-kernel.c
@@ -31,6 +31,8 @@
#include "inotify-kernel.h"
#include <sys/inotify.h>
+#include "glib-private.h"
+
/* Timings for pairing MOVED_TO / MOVED_FROM events */
#define PROCESS_EVENTS_TIME 1000 /* 1000 milliseconds (1 hz) */
#define DEFAULT_HOLD_UNTIL_TIME 0 /* 0 millisecond */
@@ -116,6 +118,7 @@ ik_source_check (GSource *source)
if (pending_count < MAX_PENDING_COUNT)
{
+ GSource *timeout_source;
unsigned int pending;
if (ioctl (inotify_instance_fd, FIONREAD, &pending) == -1)
@@ -146,8 +149,12 @@ ik_source_check (GSource *source)
ik_poll_fd_enabled = FALSE;
/* Set a timeout to re-add the PollFD to the source */
g_source_ref (source);
- g_timeout_add (TIMEOUT_MILLISECONDS, ik_source_timeout, source);
-
+
+ timeout_source = g_timeout_source_new (TIMEOUT_MILLISECONDS);
+ g_source_set_callback (timeout_source, ik_source_timeout, source, NULL);
+ g_source_attach (timeout_source, glib__private__ ()->g_get_worker_context ());
+ g_source_unref (timeout_source);
+
return FALSE;
}
@@ -211,7 +218,7 @@ gboolean _ik_startup (void (*cb)(ik_event_t *event))
g_source_set_name (source, "GIO Inotify");
g_source_add_poll (source, &ik_poll_fd);
g_source_set_callback (source, ik_read_callback, NULL, NULL);
- g_source_attach (source, NULL);
+ g_source_attach (source, glib__private__ ()->g_get_worker_context ());
g_source_unref (source);
cookie_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -359,8 +366,13 @@ ik_read_callback (gpointer user_data)
/* If the event process callback is off, turn it back on */
if (!process_eq_running && events)
{
+ GSource *timeout_source;
+
process_eq_running = TRUE;
- g_timeout_add (PROCESS_EVENTS_TIME, ik_process_eq_callback, NULL);
+ timeout_source = g_timeout_source_new (PROCESS_EVENTS_TIME);
+ g_source_set_callback (timeout_source, ik_process_eq_callback, NULL, NULL);
+ g_source_attach (timeout_source, glib__private__ ()->g_get_worker_context ());
+ g_source_unref (timeout_source);
}
G_UNLOCK (inotify_lock);
diff --git a/gio/inotify/inotify-missing.c b/gio/inotify/inotify-missing.c
index 20d89c0a0..c127ab1fd 100644
--- a/gio/inotify/inotify-missing.c
+++ b/gio/inotify/inotify-missing.c
@@ -27,6 +27,7 @@
#include <glib.h>
#include "inotify-missing.h"
#include "inotify-path.h"
+#include "glib-private.h"
#define SCAN_MISSING_TIME 4 /* 1/4 Hz */
@@ -70,8 +71,13 @@ _im_add (inotify_sub *sub)
/* If the timeout is turned off, we turn it back on */
if (!scan_missing_running)
{
+ GSource *source;
+
scan_missing_running = TRUE;
- g_timeout_add_seconds (SCAN_MISSING_TIME, im_scan_missing, NULL);
+ source = g_timeout_source_new_seconds (SCAN_MISSING_TIME);
+ g_source_set_callback (source, im_scan_missing, NULL, NULL);
+ g_source_attach (source, glib__private__ ()->g_get_worker_context ());
+ g_source_unref (source);
}
}