diff options
Diffstat (limited to 'smdirwatcher.cpp')
-rw-r--r-- | smdirwatcher.cpp | 107 |
1 files changed, 56 insertions, 51 deletions
diff --git a/smdirwatcher.cpp b/smdirwatcher.cpp index 8650d3b..8b72aab 100644 --- a/smdirwatcher.cpp +++ b/smdirwatcher.cpp @@ -9,6 +9,7 @@ #include <QMutexLocker> #include <QDateTime> #include <QDir> +#include <QSemaphore> #include <sys/inotify.h> #include <stropts.h> @@ -23,17 +24,26 @@ extern int errno; SmDirWatcher::SmDirWatcher(QObject *parent) : QThread(parent), mFd(0), mDescr(0) { - mFd = inotify_init1(IN_NONBLOCK); + mBufLen = 1024 * (sizeof(struct inotify_event) + 16); + mINdata = new char[mBufLen]; + mFd = inotify_init(); + + mCollector = new SmDataColletor(8, this); + mSemFree = new QSemaphore(1024); + mSemUsed = new QSemaphore; + mDataQueue = new QQueue<QPair<QString, DWEvent> >(); + mCollector->init(mSemFree, mSemUsed, mDataQueue); + mCollector->start(); } SmDirWatcher::~SmDirWatcher(){ if(mFd && mDescr){ inotify_rm_watch(mFd, mDescr); } + delete mINdata; } void SmDirWatcher::setDir(const QString &dir){ - QMutexLocker lock(&mWatchMx); if(mDescr){ inotify_rm_watch(mFd, mDescr); //generates IN_IGNORE ??? } @@ -44,78 +54,73 @@ void SmDirWatcher::setDir(const QString &dir){ */ mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO); mCurrent = dir; + mSemFree->acquire(); + QPair<QString, DWEvent> c = qMakePair(dir, Populate); + mDataQueue->enqueue(c); + mSemUsed->release(); } void SmDirWatcher::run(){ - QMutexLocker lock(&mWatchMx); - QVarLengthArray<char, 4096> data(4096); - int r = read(mFd, data.data(), data.size()); - int err = errno; - if(r < 0){ - if(err != EAGAIN){ - return; - } - r = read(mFd, data.data(), data.size()); - } - // inspect data - char *at = data.data(); - inotify_event *e = reinterpret_cast<inotify_event*>(at); - if(!e->len){ + int r = read(mFd, mINdata, mBufLen); + if(r <= 0){ return; } - char *end = at + data.size(); - while(at < end){ - if(e->mask & IN_IGNORED){ - at += sizeof(inotify_event) + e->len; + int i = 0; + while(i < r){ + inotify_event *e = reinterpret_cast<inotify_event*>(&mINdata[i]); + if((!e->len) || (e->mask & IN_IGNORED)){ + i += sizeof(inotify_event) + e->len; continue; } + mSemFree->acquire(); quint32 mask = e->mask; QString name = QString("%1/%2").arg(mCurrent).arg(e->name); - at += sizeof(inotify_event) + e->len; - if(mask & IN_CREATE){ - emit dwEvent(name, Added); - return; + DWEvent curEvent = None; + if(mask & IN_CREATE || mask & IN_MOVED_TO){ + curEvent = Added; } - if(mask & IN_DELETE){ - emit dwEvent(name, Deleted); - return; + if(mask & IN_DELETE || mask & IN_MOVED_FROM){ + curEvent = Deleted; } if(mask & IN_CLOSE_WRITE || e->mask & IN_MODIFY){ - emit dwEvent(name, Modified); - return; - } - if(mask & IN_MOVED_FROM || e->mask & IN_MOVED_TO){ - emit needRefresh(); - return; + curEvent = Modified; } + QPair<QString, DWEvent> c = qMakePair(name, curEvent); + mDataQueue->enqueue(c); + mSemUsed->release(); + i += sizeof(inotify_event) + e->len; } } -SmDataGatherer::SmDataGatherer(const int numFields, QObject *parent) : QThread(parent), mNumFields(numFields) {} +SmDataColletor::SmDataColletor(const int numFields, QObject *parent) : QThread(parent), mSemFree(0), mSemUsed(0), mDataQueue(0), mNumFields(numFields) {} -void SmDataGatherer::setCurrent(const QString ¤t, int mode){ - QMutexLocker lock(&mSetMx); - mCurrent = current; - mMode = mode; +void SmDataColletor::init(QSemaphore *set, QSemaphore *get, QQueue<QPair<QString, SmDirWatcher::DWEvent> > *data){ + mSemFree = set; + mSemUsed = get; + mDataQueue = data; } -void SmDataGatherer::run(){ - QMutexLocker lock(&mRunMx); - QFileInfo fi(mCurrent); - if(fi.isDir()){ - SmTreeItem *rv = populate(); - emit population(rv); - return; - } - if(fi.isFile()){ +void SmDataColletor::run(){ + forever { + mSemUsed->acquire(); + QPair<QString, SmDirWatcher::DWEvent> cur = mDataQueue->dequeue(); + if(cur.second == SmDirWatcher::Populate){ + SmTreeItem *i = populate(cur.first); + emit population(i); + mSemFree->release(); + continue; + + } + QFileInfo fi(cur.first); QList<QVariant> fd = fileData(fi); - emit newData(fd, mMode); + emit newData(fd, cur.second); + mSemFree->release(); } } -SmTreeItem * SmDataGatherer::populate(){ +SmTreeItem * SmDataColletor::populate(const QString &dir){ SmTreeItem *retval = new SmTreeItem(mNumFields); - QDir d = QDir(mCurrent); + QDir d = QDir(dir); foreach(QFileInfo fi, d.entryInfoList()){ if(fi.fileName() == "."){ continue; @@ -127,7 +132,7 @@ SmTreeItem * SmDataGatherer::populate(){ return retval; } -const QList<QVariant> SmDataGatherer::fileData(const QFileInfo &fi) const{ +const QList<QVariant> SmDataColletor::fileData(const QFileInfo &fi) const{ QList<QVariant> data; data << fi.fileName() << fi.size(); QString mime = Helper::mimeType(fi.absoluteFilePath()); |