From bf3cbafcdde36d3d3a8fabc7efe4645b40d6349e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Mar=C3=A9chal?= Date: Wed, 24 Mar 2021 22:15:01 -0400 Subject: [PATCH] win: fix race condition when starting a watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `mRunner` thread sometimes runs after a delay, leading to a state where `mRunning` is false and `pollDirectoryChanges` is called and does nothing. Signed-off-by: Paul Maréchal --- includes/win32/Watcher.h | 1 + src/win32/Watcher.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/includes/win32/Watcher.h b/includes/win32/Watcher.h index ab63c8b0..5ddd9402 100644 --- a/includes/win32/Watcher.h +++ b/includes/win32/Watcher.h @@ -36,6 +36,7 @@ class Watcher std::atomic mRunning; SingleshotSemaphore mHasStartedSemaphore; + SingleshotSemaphore mIsRunningSemaphore; mutable std::mutex mErrorMutex; std::string mError; diff --git a/src/win32/Watcher.cpp b/src/win32/Watcher.cpp index 7483671a..9e4b8bac 100644 --- a/src/win32/Watcher.cpp +++ b/src/win32/Watcher.cpp @@ -38,7 +38,7 @@ std::string Watcher::getUTF8Directory(std::wstring path) { // before returning it to the user stripNTPrefix(uft16DirectoryString); } - + int utf8length = WideCharToMultiByte( CP_UTF8, 0, @@ -239,6 +239,7 @@ void Watcher::start() { mRunner = std::thread([this] { // mRunning is set to false in the d'tor mRunning = true; + mIsRunningSemaphore.signal(); run(); }); @@ -247,11 +248,16 @@ void Watcher::start() { return; } + if (!mIsRunningSemaphore.waitFor(std::chrono::seconds(10))) { + setError("Watcher is not started"); + return; + } + QueueUserAPC([](__in ULONG_PTR self) { auto watcher = reinterpret_cast(self); watcher->pollDirectoryChanges(); watcher->mHasStartedSemaphore.signal(); - } , mRunner.native_handle(), (ULONG_PTR)this); + }, mRunner.native_handle(), (ULONG_PTR)this); if (!mHasStartedSemaphore.waitFor(std::chrono::seconds(10))) { setError("Watcher is not started");