Remove unnecessary QMutexes in QFileSystemWatcher implementations

The polling, inotify, and kqueue implementations are no longer threaded,
and as such, do not need mutexes to protect their internal data (since
QFileSystemWatcher itself is not documented as a thread-safe API).

The Windows implementation is unchanged as it uses multiple threads
explicitly.

Change-Id: Ia82510397e576bf704ce3aed3d776b58b39f7ff3
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
This commit is contained in:
Bradley T. Hughes 2012-01-11 09:00:41 +01:00 committed by Qt by Nokia
parent d6e0306a90
commit 93a466c6fc
7 changed files with 78 additions and 99 deletions

View File

@ -48,7 +48,6 @@
#include <qdebug.h>
#include <qdir.h>
#include <qfileinfo.h>
#include <qmutex.h>
#include <qset.h>
#include <qtimer.h>

View File

@ -245,8 +245,6 @@ QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@ -303,8 +301,6 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path
QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@ -331,8 +327,6 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path
void QInotifyFileSystemWatcherEngine::readFromInotify()
{
QMutexLocker locker(&mutex);
// qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify";
int buffSize = 0;

View File

@ -81,7 +81,6 @@ private Q_SLOTS:
private:
QInotifyFileSystemWatcherEngine(int fd);
int inotifyFd;
QMutex mutex;
QHash<QString, int> pathToID;
QHash<int, QString> idToPath;
QSocketNotifier notifier;

View File

@ -98,76 +98,72 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *directories)
{
QStringList p = paths;
{
QMutexLocker locker(&mutex);
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
QString path = it.next();
int fd;
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 >= (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)) {
::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;
}
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);
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)) {
::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;
}
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);
}
return p;
@ -179,29 +175,26 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
{
bool isEmpty;
QStringList p = paths;
{
QMutexLocker locker(&mutex);
if (pathToID.isEmpty())
return p;
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;
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;
::close(id < 0 ? -id : id);
::close(id < 0 ? -id : id);
it.remove();
if (id < 0)
directories->removeAll(path);
else
files->removeAll(path);
}
isEmpty = pathToID.isEmpty();
it.remove();
if (id < 0)
directories->removeAll(path);
else
files->removeAll(path);
}
isEmpty = pathToID.isEmpty();
return p;
}
@ -224,7 +217,6 @@ void QKqueueFileSystemWatcherEngine::readFromKqueue()
int fd = kev.ident;
DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter;
QMutexLocker locker(&mutex);
int id = fd;
QString path = idToPath.value(id);

View File

@ -85,7 +85,6 @@ private:
int kqfd;
QMutex mutex;
QHash<QString, int> pathToID;
QHash<int, QString> idToPath;
QSocketNotifier notifier;

View File

@ -54,7 +54,6 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@ -89,7 +88,6 @@ QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &path
QStringList *files,
QStringList *directories)
{
QMutexLocker locker(&mutex);
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@ -113,7 +111,6 @@ QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &path
void QPollingFileSystemWatcherEngine::timeout()
{
QMutexLocker locker(&mutex);
QMutableHashIterator<QString, FileInfo> fit(files);
while (fit.hasNext()) {
QHash<QString, FileInfo>::iterator x = fit.next();

View File

@ -105,7 +105,6 @@ class QPollingFileSystemWatcherEngine : public QFileSystemWatcherEngine
}
};
mutable QMutex mutex;
QHash<QString, FileInfo> files, directories;
public: