summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2010-02-16 09:56:13 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2010-02-16 09:56:13 (GMT)
commite55a5e173877a20586245eac2080ba9c6fa4de0a (patch)
treefe3c33342e7eb3e05c44389a0ea8aebf4e1fd296
parentf3a47f0fe6e9f63c030e6e89f1258d4faf2025cd (diff)
downloadQt-e55a5e173877a20586245eac2080ba9c6fa4de0a.zip
Qt-e55a5e173877a20586245eac2080ba9c6fa4de0a.tar.gz
Qt-e55a5e173877a20586245eac2080ba9c6fa4de0a.tar.bz2
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
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp18
1 files 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 {