From 527a1821e6f8e115db3335a3341c7ac491725a0d Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 13 Jun 2021 10:52:27 -0700 Subject: [PATCH] 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. --- .../windows/DirectoryWatcher-windows.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp b/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp index 6bcfb86e7f99..847d20bfbb6f 100644 --- a/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp +++ b/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp @@ -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 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 lock(Mutex); + NotifierActive = true; + } + Ready.notify_one(); + while (true) { DirectoryWatcher::Event E = Q.pop_front(); Callback(E, /*IsInitial=*/false);