From: Dana Jansens Date: Tue, 26 Jul 2011 13:40:52 +0000 (-0400) Subject: Fix blocking in inotify reader. X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=46a6124832ed1286b5af2b882a74704809467405;p=dana%2Fopenbox.git Fix blocking in inotify reader. If the inotify reader reads an event and it ends at the same place the read() ended, then we don't know that there is anything more available, so don't try read() again until after it has been poll()'d. --- diff --git a/obt/watch_inotify.c b/obt/watch_inotify.c index 336e0e07..2093a769 100644 --- a/obt/watch_inotify.c +++ b/obt/watch_inotify.c @@ -107,10 +107,10 @@ static gboolean source_read(GSource *source, GSourceFunc cb, gpointer data) gchar buffer[BUF_LEN]; gchar *name; guint name_len; /* number of bytes read for the name */ - guint event_len; /* number of bytes read for the event */ gint len; /* number of bytes in the buffer */ gint pos; /* position in the buffer */ enum { + READING_DONE, READING_EVENT, READING_NAME_BUFFER, READING_NAME_HEAP @@ -118,20 +118,19 @@ static gboolean source_read(GSource *source, GSourceFunc cb, gpointer data) struct inotify_event event; pos = BUF_LEN; - state = READING_EVENT; - len = event_len = name_len = 0; + state = READING_DONE; + len = name_len = 0; /* sometimes we can end up here even tho no events have been reported by the kernel. blame glib? but we'll block if we read in that case. */ - while (ino_source->pfd.revents) { - if (pos == len || !len || event_len) { - /* refill the buffer */ + if (ino_source->pfd.revents) + state = READING_EVENT; - if (event_len) - pos = event_len; - else - pos = 0; + while (state != READING_DONE) { + if (pos == len || !len) { + /* refill the buffer */ + pos = 0; len = read(ino_source->pfd.fd, &buffer[pos], BUF_LEN-pos); if (len < 0) { @@ -269,7 +268,11 @@ static gboolean source_read(GSource *source, GSourceFunc cb, gpointer data) if (state == READING_NAME_HEAP) g_free(name); - state = READING_EVENT; + /* is there another event in the buffer after this one */ + if (pos == len) + state = READING_DONE; + else + state = READING_EVENT; } } return TRUE;