summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-11-26 09:33:39 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-11-26 09:33:39 (GMT)
commite053119de55be1747f98d15a7871d5bcba2648b6 (patch)
tree401a3a9f36bb3850c7d82fd85f131ddd9d012826
parentd779f70e3012e85bee42e974afe6bfc7320d8302 (diff)
parent8d01c4a29b6b07a52f0aead33f108dac9e298a14 (diff)
downloadQt-e053119de55be1747f98d15a7871d5bcba2648b6.zip
Qt-e053119de55be1747f98d15a7871d5bcba2648b6.tar.gz
Qt-e053119de55be1747f98d15a7871d5bcba2648b6.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1: QFileSystemWatcher: don't try to stop non-running thread Fix QSettings auto test to use QTRY_VERIFY tst_QFileSystemWatcher: Don't exit the event loop on first signal. QPollingFileSystemWatcherEngine: Fix double report of directory change. QKqueueFileSystemWatcherEngine: Use higher file descriptors. QKqueueFileSystemWatcherEngine: Unlock mutex between two events. QKqueueFileSystemWatcherEngine: Unlock mutex before calling write(2). QKqueueFileSystemWatcherEngine: Handle kevent(2) returning EINTR. QKqueueFileSystemWatcherEngine: Deleting kevent is handled by close(). QKqueueFileSystemWatcherEngine: Use EV_CLEAR instead of EV_ONESHOT.
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp10
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp194
-rw-r--r--tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp9
-rw-r--r--tests/auto/qsettings/tst_qsettings.cpp13
4 files changed, 103 insertions, 123 deletions
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 3a7d795..4d0d495 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -228,8 +228,14 @@ void QPollingFileSystemWatcherEngine::timeout()
dit.remove();
emit directoryChanged(path, true);
} else if (x.value() != fi) {
- x.value() = fi;
- emit directoryChanged(path, false);
+ fi.refresh();
+ if (!fi.exists()) {
+ dit.remove();
+ emit directoryChanged(path, true);
+ } else {
+ x.value() = fi;
+ emit directoryChanged(path, false);
+ }
}
}
diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
index 7960792..68994d2 100644
--- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp
+++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
@@ -119,67 +119,77 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
- QMutexLocker locker(&mutex);
-
QStringList p = paths;
- QMutableListIterator<QString> it(p);
- while (it.hasNext()) {
- QString path = it.next();
- int fd;
+ {
+ QMutexLocker locker(&mutex);
+
+ QMutableListIterator<QString> it(p);
+ while (it.hasNext()) {
+ QString path = it.next();
+ int fd;
#if defined(O_EVTONLY)
- fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY);
+ fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY);
#else
- fd = qt_safe_open(QFile::encodeName(path), O_RDONLY);
+ fd = qt_safe_open(QFile::encodeName(path), O_RDONLY);
#endif
- if (fd == -1) {
- perror("QKqueueFileSystemWatcherEngine::addPaths: open");
- continue;
- }
+ if (fd == -1) {
+ perror("QKqueueFileSystemWatcherEngine::addPaths: open");
+ continue;
+ }
+ if (fd >= (int)FD_SETSIZE / 2 && fd < (int)FD_SETSIZE) {
+ int fddup = fcntl(fd, F_DUPFD, FD_SETSIZE);
+ if (fddup != -1) {
+ ::close(fd);
+ fd = fddup;
+ }
+ }
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
- QT_STATBUF st;
- if (QT_FSTAT(fd, &st) == -1) {
- perror("QKqueueFileSystemWatcherEngine::addPaths: fstat");
- ::close(fd);
- continue;
- }
- int id = (S_ISDIR(st.st_mode)) ? -fd : fd;
- if (id < 0) {
- if (directories->contains(path)) {
+ QT_STATBUF st;
+ if (QT_FSTAT(fd, &st) == -1) {
+ perror("QKqueueFileSystemWatcherEngine::addPaths: fstat");
::close(fd);
continue;
}
- } else {
- if (files->contains(path)) {
+ int id = (S_ISDIR(st.st_mode)) ? -fd : fd;
+ if (id < 0) {
+ if (directories->contains(path)) {
+ ::close(fd);
+ continue;
+ }
+ } else {
+ if (files->contains(path)) {
+ ::close(fd);
+ continue;
+ }
+ }
+
+ struct kevent kev;
+ EV_SET(&kev,
+ fd,
+ EVFILT_VNODE,
+ EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE,
+ 0,
+ 0);
+ if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) {
+ perror("QKqueueFileSystemWatcherEngine::addPaths: kevent");
::close(fd);
continue;
}
- }
- struct kevent kev;
- EV_SET(&kev,
- fd,
- EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE,
- 0,
- 0);
- if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) {
- perror("QKqueueFileSystemWatcherEngine::addPaths: kevent");
- ::close(fd);
- continue;
- }
+ it.remove();
+ if (id < 0) {
+ DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path;
+ directories->append(path);
+ } else {
+ DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path;
+ files->append(path);
+ }
- it.remove();
- if (id < 0) {
- DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path;
- directories->append(path);
- } else {
- DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path;
- files->append(path);
+ pathToID.insert(path, id);
+ idToPath.insert(id, path);
}
-
- pathToID.insert(path, id);
- idToPath.insert(id, path);
}
if (!isRunning())
@@ -194,43 +204,35 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
QStringList *files,
QStringList *directories)
{
- QMutexLocker locker(&mutex);
-
+ bool isEmpty;
QStringList p = paths;
- QMutableListIterator<QString> it(p);
- while (it.hasNext()) {
- QString path = it.next();
- int id = pathToID.take(path);
- QString x = idToPath.take(id);
- if (x.isEmpty() || x != path)
- continue;
-
- int fd = id < 0 ? -id : id;
- struct kevent kev;
- EV_SET(&kev,
- fd,
- EVFILT_VNODE,
- EV_DELETE,
- NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE,
- 0,
- 0);
- if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) {
- perror("QKqueueFileSystemWatcherEngine::removeWatch: kevent");
- }
- ::close(fd);
+ {
+ QMutexLocker locker(&mutex);
+ if (pathToID.isEmpty())
+ return p;
+
+ QMutableListIterator<QString> it(p);
+ while (it.hasNext()) {
+ QString path = it.next();
+ int id = pathToID.take(path);
+ QString x = idToPath.take(id);
+ if (x.isEmpty() || x != path)
+ continue;
- it.remove();
- if (id < 0)
- directories->removeAll(path);
- else
- files->removeAll(path);
+ ::close(id < 0 ? -id : id);
+
+ it.remove();
+ if (id < 0)
+ directories->removeAll(path);
+ else
+ files->removeAll(path);
+ }
+ isEmpty = pathToID.isEmpty();
}
- if (pathToID.isEmpty()) {
+ if (isEmpty) {
stop();
- locker.unlock();
wait();
- locker.relock();
} else {
write(kqpipe[1], "@", 1);
}
@@ -245,19 +247,15 @@ void QKqueueFileSystemWatcherEngine::stop()
void QKqueueFileSystemWatcherEngine::run()
{
- static const struct timespec ZeroTimeout = { 0, 0 };
-
forever {
+ int r;
struct kevent kev;
DEBUG() << "QKqueueFileSystemWatcherEngine: waiting for kevents...";
- int r = kevent(kqfd, 0, 0, &kev, 1, 0);
+ EINTR_LOOP(r, kevent(kqfd, 0, 0, &kev, 1, 0));
if (r < 0) {
perror("QKqueueFileSystemWatcherEngine: error during kevent wait");
return;
- }
-
- QMutexLocker locker(&mutex);
- do {
+ } else {
int fd = kev.ident;
DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter;
@@ -289,6 +287,8 @@ void QKqueueFileSystemWatcherEngine::run()
break;
}
} else {
+ QMutexLocker locker(&mutex);
+
int id = fd;
QString path = idToPath.value(id);
if (path.isEmpty()) {
@@ -297,12 +297,12 @@ void QKqueueFileSystemWatcherEngine::run()
path = idToPath.value(id);
if (path.isEmpty()) {
DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent for a file we're not watching";
- goto process_next_event;
+ continue;
}
}
if (kev.filter != EVFILT_VNODE) {
DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent with the wrong filter";
- goto process_next_event;
+ continue;
}
if ((kev.fflags & (NOTE_DELETE | NOTE_REVOKE | NOTE_RENAME)) != 0) {
@@ -317,31 +317,15 @@ void QKqueueFileSystemWatcherEngine::run()
else
emit fileChanged(path, true);
} else {
- DEBUG() << path << "changed, re-enabling watch";
+ DEBUG() << path << "changed";
if (id < 0)
emit directoryChanged(path, false);
else
emit fileChanged(path, false);
-
- // renable the watch
- EV_SET(&kev,
- fd,
- EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE,
- 0,
- 0);
- if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) {
- perror("QKqueueFileSystemWatcherEngine::processKqueueEvents: kevent EV_ADD");
- }
}
}
-
- // are there any more?
-process_next_event:
- r = kevent(kqfd, 0, 0, &kev, 1, &ZeroTimeout);
- } while (r > 0);
+ }
}
}
diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index fd898ee..648b7e9 100644
--- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -137,14 +137,11 @@ void tst_QFileSystemWatcher::basicTest()
// create watcher, forcing it to use a specific backend
QFileSystemWatcher watcher;
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
+ watcher.removePath(testFile.fileName());
watcher.addPath(testFile.fileName());
QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
QEventLoop eventLoop;
- connect(&watcher,
- SIGNAL(fileChanged(const QString &)),
- &eventLoop,
- SLOT(quit()));
QTimer timer;
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
@@ -280,10 +277,6 @@ void tst_QFileSystemWatcher::watchDirectory()
QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
QEventLoop eventLoop;
- connect(&watcher,
- SIGNAL(directoryChanged(const QString &)),
- &eventLoop,
- SLOT(quit()));
QTimer timer;
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp
index 0395eff..0813e28 100644
--- a/tests/auto/qsettings/tst_qsettings.cpp
+++ b/tests/auto/qsettings/tst_qsettings.cpp
@@ -51,6 +51,7 @@
#include <QtCore/QMetaType>
#include <QtCore/QtDebug>
#include <QtCore/QString>
+#include "../../shared/util.h"
#if !defined(Q_OS_SYMBIAN)
# include <cctype>
@@ -1726,26 +1727,22 @@ void tst_QSettings::testUpdateRequestEvent()
settings1.setValue("key1", 1);
QVERIFY(QFileInfo("foo").size() == 0);
- qApp->processEvents();
- QVERIFY(QFileInfo("foo").size() > 0);
+ QTRY_VERIFY(QFileInfo("foo").size() > 0);
settings1.remove("key1");
QVERIFY(QFileInfo("foo").size() > 0);
- qApp->processEvents();
- QVERIFY(QFileInfo("foo").size() == 0);
+ QTRY_VERIFY(QFileInfo("foo").size() == 0);
settings1.setValue("key2", 2);
QVERIFY(QFileInfo("foo").size() == 0);
- qApp->processEvents();
- QVERIFY(QFileInfo("foo").size() > 0);
+ QTRY_VERIFY(QFileInfo("foo").size() > 0);
settings1.clear();
QVERIFY(QFileInfo("foo").size() > 0);
- qApp->processEvents();
- QVERIFY(QFileInfo("foo").size() == 0);
+ QTRY_VERIFY(QFileInfo("foo").size() == 0);
}
const int NumIterations = 5;