summaryrefslogtreecommitdiffstats
path: root/smdirwatcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'smdirwatcher.cpp')
-rw-r--r--smdirwatcher.cpp107
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 &current, 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());