forked from OSchip/llvm-project
DirectoryWatcher: also wait for the notifier thread
Ultimately the DirectoryWatcher is not ready until the notifier thread is also active. Failure to wait for the notifier thread may result in loss of events. While this is not catastrophic in practice, the tests are sensitive to this as depending on the thread scheduler, the thread may fail to being execution before the operations are completed by the fixture. Running this in a tight loop shows no regressions locally as previously, but this failure mode was been sighted once on a builder.
This commit is contained in:
parent
7d4c8a2b8f
commit
527a1821e6
|
@ -40,6 +40,7 @@ class DirectoryWatcherWindows : public clang::DirectoryWatcher {
|
|||
|
||||
std::mutex Mutex;
|
||||
bool WatcherActive = false;
|
||||
bool NotifierActive = false;
|
||||
std::condition_variable Ready;
|
||||
|
||||
class EventQueue {
|
||||
|
@ -117,7 +118,9 @@ DirectoryWatcherWindows::DirectoryWatcherWindows(
|
|||
});
|
||||
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
Ready.wait(lock, [this] { return this->WatcherActive; });
|
||||
Ready.wait(lock, [this] {
|
||||
return this->WatcherActive && this->NotifierActive;
|
||||
});
|
||||
}
|
||||
|
||||
DirectoryWatcherWindows::~DirectoryWatcherWindows() {
|
||||
|
@ -227,6 +230,12 @@ void DirectoryWatcherWindows::NotifierThreadProc(bool WaitForInitialSync) {
|
|||
if (!WaitForInitialSync)
|
||||
this->InitialScan();
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
NotifierActive = true;
|
||||
}
|
||||
Ready.notify_one();
|
||||
|
||||
while (true) {
|
||||
DirectoryWatcher::Event E = Q.pop_front();
|
||||
Callback(E, /*IsInitial=*/false);
|
||||
|
|
Loading…
Reference in New Issue