void Win32FSHook::handlePendingActions() { debug("+Win32FSHook::handlePendingActions called"); EnterCriticalSection(&_cSection); while (_isRunning && _pendingActions.size() > 0) { debug("Win32FSHook::iteration"); pair<ACTION, int> action = _pendingActions.front(); _pendingActions.pop(); switch (action.first) { case WATCH: { debug("Win32FSHook::handlePendingActions WATCH"); int wd = action.second; map <int, WatchData*>::const_iterator i = _wid2WatchData.find(wd); if (i == _wid2WatchData.end()) { debug("WATCH: watch id %d not found", wd); } else { WatchData* watchData = i->second; watchDirectory(watchData); watchData->signalEvent(); } } break; case CANCEL: { debug("Win32FSHook::handlePendingActions CANCEL"); int wd = action.second; map <int, WatchData*>::const_iterator i = _wid2WatchData.find(wd); if (i == _wid2WatchData.end()) { debug("CANCEL: watch id %d not found", wd); } else { debug("Win32FSHook::handlePendingActions - calling unwatch ptr=%d", i->second); WatchData* watchData = i->second; // unwatching the watchdata cause the watch signal object // to be triggered. unwatchDirectory(watchData); } } break; } } LeaveCriticalSection(&_cSection); debug("-Win32FSHook::handlePendingActions"); }
static void listDirectory(const char * directory) { WIN32_FIND_DATA ffd; HANDLE fHandle; watchDirectory(directory); const char * directoryQueryString = createDirectoryQueryString(directory); fHandle = FindFirstFile(directoryQueryString, &ffd); if (INVALID_HANDLE_VALUE == fHandle) { printf("Failed to list directory!\n"); return; } do { const char * fullPath; if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,"..")) { fullPath = concatDirAndFileName(directory,ffd.cFileName,true); listDirectory(fullPath); free((void*)fullPath); } else if (isLuaFile(ffd.cFileName)) { int pos; fullPath = concatDirAndFileName(directory,ffd.cFileName,false); bool isNew = findFilePosition(fullPath,&pos); if (isNew) { newFileInfoOnPos(fullPath,&ffd,pos); } else if (CompareFileTime(&ffd.ftLastWriteTime,&filesInfo[pos]->lastwrite) == 1) { reloadLuaFile(filesInfo[pos]->fileName); filesInfo[pos]->lastwrite = ffd.ftLastWriteTime; } filesInfo[pos]->shouldDelete = false; free((void*)fullPath); } } while (FindNextFile(fHandle, &ffd) != 0); free((void*)directoryQueryString); }
void FileContentProvider::watch() { boost::filesystem::path watchDir = _filepath.parent_path(); initInotify(); watchDirectory(watchDir); while (true) { LOG_DEBUG(filecontentproviderlog) << "[FileContentProvider] watching directory " << watchDir << std::endl; if (!checkEvents()) { LOG_DEBUG(filecontentproviderlog) << "[FileContentProvider] got an interrupt signal" << std::endl; break; } inotify_event* event = readInotifyEvent(); if (event == NULL ) break; LOG_ALL(filecontentproviderlog) << "directory " << watchDir << " changed!" << std::endl; LOG_ALL(filecontentproviderlog) << "\tmask is: " << event->mask << std::endl; LOG_ALL(filecontentproviderlog) << "\tname is: " << event->name << std::endl; if (strcmp(event->name, _filepath.leaf().c_str()) != 0) { LOG_ALL(filecontentproviderlog) << "file " << event->name << " changed, but I'm interested in " << _filepath.leaf() << std::endl; continue; } processInotifyEvent(event); } unwatchDirectory(watchDir); tearDownInotify(); }
/** * This is the watcher thread main stuff. It iterates on watching its 'known' directories and * notifying the associated filter with the directories/files changes. */ void Watcher::run() { QTime passStart; int numEntries = 0; const QList<PathSegment *> *pathsP = NULL; // do nothing if no root url set if (m_url.isEmpty()) return; m_stop = false; m_numWatchedFiles = 0; // we'll start by scanning this one m_files.addPath(m_url, true); do { passStart.restart(); #ifdef _VERBOSE_WATCHER qDebug() << "(File)Watcher does a pass at " << passStart; #endif // now, don't let the filter play concurrently if (!tryAcquireWatchSemaphore()) goto nextPass; // check for new or modified files/directories pathsP = m_files.getPaths(true); numEntries = pathsP->count(); for (int i = 0; !m_stop && i < numEntries; i++) { QString filepath = pathsP->at(i)->getPath(); // show progress displayActivity(tr("Scanning directory %1").arg(filepath)); displayProgress(0, numEntries - 1, i); watchDirectory(filepath); } // add the new files and directories to the watch lists #ifdef _VERBOSE_PATH m_files.dump("dumping watched files before merging"); m_newFiles.dump("dumping new files before merging"); #endif m_files.merge(&m_newFiles); m_newFiles.deleteAll(); #ifdef _VERBOSE_PATH m_files.dump("dumping watched files after merging"); m_newFiles.dump("dumping new files after merging"); #endif // now check if any of the watched files have disappeared // check removed directories for (QList<PathSegment *>::const_iterator i = m_files.getPaths(true)->begin(); i != m_files.getPaths(true)->end(); i++) { QString filepath = (*i)->getPath(); QFileInfoExt entryInfo(filepath); if (!entryInfo.exists()) { // we DO NOT need to check the content and signal for everything... // because the content will be checked later on... #ifdef _VERBOSE_WATCHER qDebug() << "Detected deleted directory " << filepath; #endif directoryDeleted(filepath); m_removedFiles.addPath(filepath, true); } } // check removed files for (QList<PathSegment *>::const_iterator i = m_files.getPaths()->begin(); !m_stop && i != m_files.getPaths()->end(); i++) { QString filepath = (*i)->getPath(); QFileInfoExt entryInfo(filepath); if (!entryInfo.exists()) { #ifdef _VERBOSE_WATCHER qDebug() << "Detected deleted file " << filepath; #endif // fileDeleted(filepath); fileDeleted(entryInfo.absoluteFilePath()); m_removedFiles.addPath(filepath); --m_numWatchedFiles; } } // and remove // directories for (QList<PathSegment *>::const_iterator i = m_removedFiles.getPaths(true)->begin(); i != m_removedFiles.getPaths(true)->end(); i++) m_files.deletePath((*i)->getPath(), true); // files for (QList<PathSegment *>::const_iterator i = m_removedFiles.getPaths()->begin(); !m_stop && i != m_removedFiles.getPaths()->end(); i++) m_files.deletePath((*i)->getPath()); m_removedFiles.deleteAll(); // keep last pass time m_lastPass = QDateTime::currentDateTime(); // now, the filter can play releaseWatchSemaphore(); nextPass: #ifdef _VERBOSE_WATCHER qDebug() << "(File)Watcher ends pass at " << m_lastPass << " (duration: " << passStart.elapsed() << " ms)"; #endif QString duration; duration.sprintf("%d", passStart.elapsed()); displayActivity(tr("Scanning pass completed in (%1) milliseconds. Now sleeping.").arg(duration)); displayProgress(1, 100, 100); // a little break if (!m_stop) msleep(WATCH_PASS_INTERVAL); } while (!m_stop); #ifdef _VERBOSE_WATCHER qDebug() << "(File)Watcher now EXITING!"; #endif }
void OsmAnd::ObfsCollection::watchDirectory( const QString& dirPath, bool recursive /*= true*/ ) { watchDirectory(QDir(dirPath), recursive); }