On Monday 09 August 2010 11:01:56 Tijl Coosemans wrote:
> I've attached what I believe to be the final version of the kdelibs
> patch. It uses polling by default for NFS mounts now and fixes a few
> other things. Unless someone finds a problem with it, I'll submit that
> as well.

hey tijl, thanks for working on this!

but... i've applied the patches (attached... the kde one was rewritten 
for kde 4.5 by dima) to my system and the performance is terrible

some (maybe useless) details:
CPU: Intel(R) Core(TM) Duo CPU      T2300  @ 1.66GHz
real memory  = 1610612736 (1536 MB)
FreeBSD echo.hoth 9.0-CURRENT FreeBSD 9.0-CURRENT #4 r211492: 
Thu Aug 19 23:52:10 CEST 2010     
r...@echo.hoth:/usr/obj/usr/src/sys/TPR60  i386
qt-4.7.0.b2
kde-4.5.0
just for reference... i don't have any NFS mount
i don't think anything's missing...

what happens:
lots of processes go into kqread and ucond (which, i've understood, is 
related to i/o) statuses, and long time passes before they're still 
usable, just like (snapshot taken right now)...
- ucond   1   2:38  1.46% kdeinit4: kdeinit4: konqueror --silent 
(kdeinit4)
- kqread  1   1:45  0.10% /usr/local/kde4/bin/kontact
- ucond   0   1:33  0.00% /usr/local/kde4/bin/amarok
- ucond   0   0:39  0.00% /usr/local/bin/virtuoso-t +foreground 
+configfile /tmp/vir
- kqread  0   0:23  0.00% kdeinit4: kdeinit4: kmix (kdeinit4)
- ucond   0   0:17  0.00% /usr/local/kde4/bin/nepomukservicestub 
nepomukstrigiservic
- kqread  0   0:14  0.00% kwin (this one makes the whole system 
completely unusable)
- kqread  1   0:03  0.00% kdeinit4: kdeinit4: krunner --nocrashhandler 
(kdeinit4)
- ucond   1   0:02  0.00% /usr/local/kde4/bin/knotify4
- kqread  0   0:02  0.00% /usr/local/kde4/bin/konversation -caption 
Konversation -ic
- kqread  0   0:01  0.00% kdeinit4: kdeinit4: kwalletd (kdeinit4)
- kqread  0   0:01  0.00% /usr/local/kde4/bin/nepomukservicestub 
nepomukontologyload

i know less than zero on this matter, so, please, let me know how can i 
be more useful :)
-- 
Alberto Villa, FreeBSD Committer <avi...@freebsd.org>
http://people.FreeBSD.org/~avilla

No woman can endure a gambling husband, unless he is a steady 
winner.
                -- Lord Thomas Robert Dewar
--- 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);
       }
     }
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);
+        }
     }
 }
 

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
kde-freebsd mailing list
kde-freebsd@kde.org
https://mail.kde.org/mailman/listinfo/kde-freebsd
See also http://freebsd.kde.org/ for latest information

Reply via email to