From e55a5e173877a20586245eac2080ba9c6fa4de0a Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 16 Feb 2010 10:56:13 +0100 Subject: Fix a deadlock in kqueue implementation of QFileSystemWatcher When adding and removing lots of files, the kqueue implementation's pipe between the worker thread and the main interface would fill up, causing the thread adding/removing files to block even though the worker thread was no longer running. The kqueue interface gives us information about how much data is available on the pipe (the data member of the kevent struct), so we should use this to make sure we always empty the pipe. We then iterate over all the command bytes and make sure we interpret them correctly. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index f088ded..731406f 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -260,12 +260,22 @@ void QKqueueFileSystemWatcherEngine::run() DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter; if (fd == kqpipe[0]) { - char c; - if (read(kqpipe[0], &c, 1) != 1) { + // read all pending data from the pipe + QByteArray ba; + ba.resize(kev.data); + if (read(kqpipe[0], ba.data(), ba.size()) != ba.size()) { perror("QKqueueFileSystemWatcherEngine: error reading from pipe"); return; } - switch (c) { + // read the command from the buffer (but break and return on 'q') + char cmd = 0; + for (int i = 0; i < ba.size(); ++i) { + cmd = ba.constData()[i]; + if (cmd == 'q') + break; + } + // handle the command + switch (cmd) { case 'q': DEBUG() << "QKqueueFileSystemWatcherEngine: thread received 'q', exiting..."; return; @@ -273,7 +283,7 @@ void QKqueueFileSystemWatcherEngine::run() DEBUG() << "QKqueueFileSystemWatcherEngine: thread received '@', continuing..."; break; default: - DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << c; + DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << cmd; break; } } else { -- cgit v0.12