Skip to content

Commit 1c26b58

Browse files
committed
Optional force scan for DirectoryWatcher pocoproject#853
1 parent 5b80826 commit 1c26b58

2 files changed

Lines changed: 41 additions & 20 deletions

File tree

‎Foundation/include/Poco/DirectoryWatcher.h‎

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class Foundation_API DirectoryWatcher: protected Runnable
6363
/// Therefore, the interval in which scans are done can be specified in
6464
/// the constructor. Note that periodic scanning will also be done on FreeBSD
6565
/// and Darwin if events for changes to files (DW_ITEM_MODIFIED) are enabled.
66+
/// To avoid problems (e.g. with network shares notifications), scanning
67+
/// can be forced as the only mechanism, regardless of platform default.
6668
///
6769
/// DW_ITEM_MOVED_FROM and DW_ITEM_MOVED_TO events will only be reported
6870
/// on Linux. On other platforms, a file rename or move operation
@@ -134,21 +136,29 @@ class Foundation_API DirectoryWatcher: protected Runnable
134136
BasicEvent<const Exception> scanError;
135137
/// Fired when an error occurs while scanning for changes.
136138

137-
DirectoryWatcher(const std::string& path, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
139+
DirectoryWatcher(const std::string& path,
140+
int eventMask = DW_FILTER_ENABLE_ALL,
141+
int scanInterval = DW_DEFAULT_SCAN_INTERVAL,
142+
bool forceScan = false);
138143
/// Creates a DirectoryWatcher for the directory given in path.
139144
/// To enable only specific events, an eventMask can be specified by
140145
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
141146
/// On platforms where no native filesystem notifications are available,
142147
/// scanInterval specifies the interval in seconds between scans
143-
/// of the directory.
148+
/// of the directory. Native notification mechanism can also be disabled
149+
/// (i.e. replaced with scanning) by setting forceScan to true.
144150

145-
DirectoryWatcher(const File& directory, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
151+
DirectoryWatcher(const File& directory,
152+
int eventMask = DW_FILTER_ENABLE_ALL,
153+
int scanInterval = DW_DEFAULT_SCAN_INTERVAL,
154+
bool forceScan = false);
146155
/// Creates a DirectoryWatcher for the specified directory
147156
/// To enable only specific events, an eventMask can be specified by
148157
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
149158
/// On platforms where no native filesystem notifications are available,
150159
/// scanInterval specifies the interval in seconds between scans
151-
/// of the directory.
160+
/// of the directory. Native notification mechanism can also be disabled
161+
/// (i.e. replaced with scanning) by setting forceScan to true.
152162

153163
~DirectoryWatcher();
154164
/// Destroys the DirectoryWatcher.
@@ -186,11 +196,12 @@ class Foundation_API DirectoryWatcher: protected Runnable
186196
DirectoryWatcher(const DirectoryWatcher&);
187197
DirectoryWatcher& operator = (const DirectoryWatcher&);
188198

189-
Thread _thread;
190-
File _directory;
191-
int _eventMask;
192-
AtomicCounter _eventsSuspended;
193-
int _scanInterval;
199+
Thread _thread;
200+
File _directory;
201+
int _eventMask;
202+
AtomicCounter _eventsSuspended;
203+
int _scanInterval;
204+
bool _forceScan;
194205
DirectoryWatcherStrategy* _pStrategy;
195206
};
196207

‎Foundation/src/DirectoryWatcher.cpp‎

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ class BSDDirectoryWatcherStrategy: public DirectoryWatcherStrategy
468468
};
469469

470470

471-
#else
471+
#endif
472472

473473

474474
class PollingDirectoryWatcherStrategy: public DirectoryWatcherStrategy
@@ -518,22 +518,24 @@ class PollingDirectoryWatcherStrategy: public DirectoryWatcherStrategy
518518
};
519519

520520

521-
#endif
522521

523-
524-
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval):
522+
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval,
523+
bool forceScan) :
525524
_directory(path),
526525
_eventMask(eventMask),
527-
_scanInterval(scanInterval)
526+
_scanInterval(scanInterval),
527+
_forceScan(forceScan)
528528
{
529529
init();
530530
}
531531

532532

533-
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval):
533+
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval,
534+
bool forceScan) :
534535
_directory(directory),
535536
_eventMask(eventMask),
536-
_scanInterval(scanInterval)
537+
_scanInterval(scanInterval),
538+
_forceScan(forceScan)
537539
{
538540
init();
539541
}
@@ -575,15 +577,23 @@ void DirectoryWatcher::init()
575577
if (!_directory.isDirectory())
576578
throw Poco::InvalidArgumentException("not a directory", _directory.path());
577579

580+
if (!_forceScan)
581+
{
578582
#if POCO_OS == POCO_OS_WINDOWS_NT
579-
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
583+
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
580584
#elif POCO_OS == POCO_OS_LINUX
581-
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
585+
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
582586
#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD
583-
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
587+
_pStrategy = new BSDDirectoryWatcherStrategy(*this);
584588
#else
585-
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
589+
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
586590
#endif
591+
}
592+
else
593+
{
594+
_pStrategy = new PollingDirectoryWatcherStrategy(*this);
595+
}
596+
587597
_thread.start(*this);
588598
}
589599

0 commit comments

Comments
 (0)