[kde-freebsd] QFilesSystemWatcher instead of polling/FAM
Tijl Coosemans
tijl at coosemans.org
Mon Sep 20 23:35:02 CEST 2010
On Monday 20 September 2010 19:25:56 Max Brazhnikov wrote:
> On Sun, 19 Sep 2010 23:03:32 +0200, Tijl Coosemans wrote:
>> On Sunday 19 September 2010 20:10:48 Max Brazhnikov wrote:
>>> We can commit the patches to ports and wait until they will be
>>> merged upstream.
>>
>> That's ok for me. I'll be here to help if more problems do turn up.
>
> Should we use you latest patches you've sent to the list, or you have
> updated ones?
The latest patches I sent to the list. Someone ported them to KDE 4.5.
In any case, I've attached the patches I've been using.
-------------- next part --------------
--- kdecore/CMakeLists.txt.orig 2010-06-24 14:08:17.000000000 +0200
+++ kdecore/CMakeLists.txt 2010-06-24 14:08:42.000000000 +0200
@@ -15,11 +15,9 @@
check_include_files(sys/inotify.h SYS_INOTIFY_H_FOUND)
macro_bool_to_01(SYS_INOTIFY_H_FOUND HAVE_SYS_INOTIFY_H)
-if(WIN32)
- # currently for win32 only, since it doesn't support watching files that don't exist yet
- option(USE_QFILESYSTEMWATCHER "Use QFileSystemWatcher instead polling for KDirWatch" ON)
- macro_bool_to_01(USE_QFILESYSTEMWATCHER HAVE_QFILESYSTEMWATCHER)
-endif(WIN32)
+
+option(USE_QFILESYSTEMWATCHER "Use QFileSystemWatcher instead polling for KDirWatch" ON)
+macro_bool_to_01(USE_QFILESYSTEMWATCHER HAVE_QFILESYSTEMWATCHER)
# Generate io/config-kdirwatch.h
include(io/ConfigureChecks.cmake)
--- kdecore/io/kdirwatch_p.h.orig 2010-06-24 15:21:37.000000000 +0200
+++ kdecore/io/kdirwatch_p.h 2010-06-24 15:21:58.000000000 +0200
@@ -102,7 +102,7 @@
QHash<QString,QFileSystemWatcher*> m_paths;
};
#else
-typedef KFileSystemWatcher QFileSystemWatcher;
+typedef QFileSystemWatcher KFileSystemWatcher;
#endif
#endif
--- kdecore/io/kdirwatch.cpp.orig 2010-02-26 19:30:10.000000000 +0100
+++ kdecore/io/kdirwatch.cpp 2010-08-08 20:39:38.000000000 +0200
@@ -94,7 +94,7 @@ static KDirWatchPrivate::WatchMethod met
#ifdef Q_OS_WIN
return KDirWatchPrivate::QFSWatch;
#elif defined(Q_OS_FREEBSD)
- return KDirWatchPrivate::Stat;
+ return KDirWatchPrivate::QFSWatch;
#else
return KDirWatchPrivate::INotify;
#endif
@@ -150,7 +150,11 @@ KDirWatchPrivate::KDirWatchPrivate()
m_preferredMethod = methodFromString(method);
// The nfs method defaults to the normal (local) method
+#if defined(Q_OS_FREEBSD)
+ m_nfsPreferredMethod = methodFromString(config.readEntry("nfsPreferredMethod", "Stat"));
+#else
m_nfsPreferredMethod = methodFromString(config.readEntry("nfsPreferredMethod", method));
+#endif
QStringList availableMethods;
@@ -961,7 +965,16 @@ void KDirWatchPrivate::removeEntry(KDirW
#ifdef HAVE_QFILESYSTEMWATCHER
if (e->m_mode == QFSWatchMode) {
- fsWatcher->removePath(e->path);
+ if ( e->m_status == Normal ) {
+ fsWatcher->removePath(e->path);
+ kDebug(7001).nospace() << "Cancelled QFSWatch for " << e->path;
+ }
+ else {
+ if (e->isDir)
+ removeEntry(0, QDir::cleanPath(e->path+"/.."), e);
+ else
+ removeEntry(0, QFileInfo(e->path).absolutePath(), e);
+ }
}
#endif
if (e->m_mode == StatMode) {
@@ -1595,8 +1608,7 @@ void KDirWatchPrivate::fswEventReceived(
EntryMap::Iterator it;
it = m_mapEntries.find(path);
if(it != m_mapEntries.end()) {
- Entry entry = *it; // deep copy to not point to uninialized data (can happen inside emitEvent() )
- Entry *e = &entry;
+ Entry *e = &(*it);
e->dirty = true;
int ev = scanEntry(e);
if (ev != NoChange)
@@ -1607,28 +1619,20 @@ void KDirWatchPrivate::fswEventReceived(
else
addEntry(0, QFileInfo(e->path).absolutePath(), e, true);
} else
+ if(ev == Created) {
+ if(!useQFSWatch(e))
+#ifdef HAVE_SYS_INOTIFY_H
+ if(!useINotify(e))
+#endif
+ useStat(e);
+ } else
if (ev == Changed && e->isDir && e->m_entries.count()) {
Entry* sub_entry = 0;
Q_FOREACH(sub_entry, e->m_entries) {
- if(e->isDir) { // ####### !?!? Already checked above
- if (QFileInfo(sub_entry->path).isDir()) // ##### !? no comparison between sub_entry->path and path?
- break;
- } else {
- if (QFileInfo(sub_entry->path).isFile())
- break;
- }
+ if (QFileInfo(sub_entry->path).exists())
+ break;
}
if (sub_entry) {
- removeEntry(0, e, sub_entry);
- //KDE_struct_stat stat_buf;
- //QByteArray tpath = QFile::encodeName(path);
- //KDE_stat(tpath, &stat_buf);
-
- if(!useQFSWatch(sub_entry))
-#ifdef HAVE_SYS_INOTIFY_H
- if(!useINotify(sub_entry))
-#endif
- useStat(sub_entry);
fswEventReceived(sub_entry->path);
}
}
-------------- next part --------------
diff --git src/corelib/io/qfilesystemwatcher_kqueue.cpp src/corelib/io/qfilesystemwatcher_kqueue.cpp
index 99c165e..ce79cf7 100644
--- src/corelib/io/qfilesystemwatcher_kqueue.cpp
+++ src/corelib/io/qfilesystemwatcher_kqueue.cpp
@@ -133,6 +133,14 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
perror("QKqueueFileSystemWatcherEngine::addPaths: open");
continue;
}
+ if (fd >= FD_SETSIZE / 2 && fd < 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) {
@@ -157,7 +165,7 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
EV_SET(&kev,
fd,
EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
+ EV_ADD | EV_ENABLE | EV_CLEAR,
NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE,
0,
0);
@@ -180,6 +188,8 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
idToPath.insert(id, path);
}
+ locker.unlock();
+
if (!isRunning())
start();
else
@@ -203,19 +213,7 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
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);
+ ::close(id < 0 ? -id : id);
it.remove();
if (id < 0)
@@ -225,11 +223,11 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
}
if (pathToID.isEmpty()) {
+ locker.unlock();
stop();
- locker.unlock();
wait();
- locker.relock();
} else {
+ locker.unlock();
write(kqpipe[1], "@", 1);
}
@@ -243,19 +241,18 @@ void QKqueueFileSystemWatcherEngine::stop()
void QKqueueFileSystemWatcherEngine::run()
{
- static const struct timespec ZeroTimeout = { 0, 0 };
-
forever {
struct kevent kev;
DEBUG() << "QKqueueFileSystemWatcherEngine: waiting for kevents...";
int r = kevent(kqfd, 0, 0, &kev, 1, 0);
if (r < 0) {
+ if(errno == EINTR) {
+ DEBUG() << "QKqueueFileSystemWatcherEngine: kevent call was interrupted, restarting...";
+ continue;
+ }
perror("QKqueueFileSystemWatcherEngine: error during kevent wait");
return;
- }
-
- QMutexLocker locker(&mutex);
- do {
+ } else {
int fd = kev.ident;
DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter;
@@ -287,6 +284,8 @@ void QKqueueFileSystemWatcherEngine::run()
break;
}
} else {
+ QMutexLocker locker(&mutex);
+
int id = fd;
QString path = idToPath.value(id);
if (path.isEmpty()) {
@@ -315,30 +314,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?
- r = kevent(kqfd, 0, 0, &kev, 1, &ZeroTimeout);
- } while (r > 0);
+ }
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part.
Url : http://mail.kde.org/pipermail/kde-freebsd/attachments/20100920/c42a8953/attachment.sig
More information about the kde-freebsd
mailing list