Optional force scan for DirectoryWatcher #853

This commit is contained in:
unknown 2015-06-03 14:55:05 -05:00
parent 5b80826437
commit 1c26b58452
2 changed files with 41 additions and 20 deletions

View File

@ -63,6 +63,8 @@ class Foundation_API DirectoryWatcher: protected Runnable
/// Therefore, the interval in which scans are done can be specified in
/// the constructor. Note that periodic scanning will also be done on FreeBSD
/// and Darwin if events for changes to files (DW_ITEM_MODIFIED) are enabled.
/// To avoid problems (e.g. with network shares notifications), scanning
/// can be forced as the only mechanism, regardless of platform default.
///
/// DW_ITEM_MOVED_FROM and DW_ITEM_MOVED_TO events will only be reported
/// on Linux. On other platforms, a file rename or move operation
@ -134,21 +136,29 @@ public:
BasicEvent<const Exception> scanError;
/// Fired when an error occurs while scanning for changes.
DirectoryWatcher(const std::string& path, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
DirectoryWatcher(const std::string& path,
int eventMask = DW_FILTER_ENABLE_ALL,
int scanInterval = DW_DEFAULT_SCAN_INTERVAL,
bool forceScan = false);
/// Creates a DirectoryWatcher for the directory given in path.
/// To enable only specific events, an eventMask can be specified by
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
/// On platforms where no native filesystem notifications are available,
/// scanInterval specifies the interval in seconds between scans
/// of the directory.
/// of the directory. Native notification mechanism can also be disabled
/// (i.e. replaced with scanning) by setting forceScan to true.
DirectoryWatcher(const File& directory, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
DirectoryWatcher(const File& directory,
int eventMask = DW_FILTER_ENABLE_ALL,
int scanInterval = DW_DEFAULT_SCAN_INTERVAL,
bool forceScan = false);
/// Creates a DirectoryWatcher for the specified directory
/// To enable only specific events, an eventMask can be specified by
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
/// On platforms where no native filesystem notifications are available,
/// scanInterval specifies the interval in seconds between scans
/// of the directory.
/// of the directory. Native notification mechanism can also be disabled
/// (i.e. replaced with scanning) by setting forceScan to true.
~DirectoryWatcher();
/// Destroys the DirectoryWatcher.
@ -186,11 +196,12 @@ private:
DirectoryWatcher(const DirectoryWatcher&);
DirectoryWatcher& operator = (const DirectoryWatcher&);
Thread _thread;
File _directory;
int _eventMask;
AtomicCounter _eventsSuspended;
int _scanInterval;
Thread _thread;
File _directory;
int _eventMask;
AtomicCounter _eventsSuspended;
int _scanInterval;
bool _forceScan;
DirectoryWatcherStrategy* _pStrategy;
};

View File

@ -468,7 +468,7 @@ private:
};
#else
#endif
class PollingDirectoryWatcherStrategy: public DirectoryWatcherStrategy
@ -518,22 +518,24 @@ private:
};
#endif
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval):
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval,
bool forceScan) :
_directory(path),
_eventMask(eventMask),
_scanInterval(scanInterval)
_scanInterval(scanInterval),
_forceScan(forceScan)
{
init();
}
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval):
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval,
bool forceScan) :
_directory(directory),
_eventMask(eventMask),
_scanInterval(scanInterval)
_scanInterval(scanInterval),
_forceScan(forceScan)
{
init();
}
@ -575,15 +577,23 @@ void DirectoryWatcher::init()
if (!_directory.isDirectory())
throw Poco::InvalidArgumentException("not a directory", _directory.path());
if (!_forceScan)
{
#if POCO_OS == POCO_OS_WINDOWS_NT
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
#elif POCO_OS == POCO_OS_LINUX
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
#else
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
#endif
}
else
{
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
}
_thread.start(*this);
}