Skip to content

Commit

Permalink
watchdog: avoid data races in watchdog
Browse files Browse the repository at this point in the history
asan thread sanitizer reported data races in the watchdog from reading
and setting the bool variables make them std::atomic bools. also add a
atomic bool for the main thread to wait for to avoid data race when
reading the config values.
  • Loading branch information
gulafaran committed Aug 11, 2024
1 parent 8b943e6 commit 48fde62
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 11 deletions.
3 changes: 3 additions & 0 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {

g_pConfigManager->init();
g_pWatchdog = std::make_unique<CWatchdog>(); // requires config
// wait for watchdog to initialize to not hit data races in reading config values.
while (!g_pWatchdog->m_bWatchdogInitialized)
std::this_thread::yield();

Debug::log(LOG, "Creating the PointerManager!");
g_pPointerManager = std::make_unique<CPointerManager>();
Expand Down
13 changes: 6 additions & 7 deletions src/helpers/Watchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ CWatchdog::CWatchdog() {
m_pWatchdog = std::make_unique<std::thread>([this] {
static auto PTIMEOUT = CConfigValue<Hyprlang::INT>("debug:watchdog_timeout");

while (1337) {
std::unique_lock lk(m_mWatchdogMutex);
m_bWatchdogInitialized = true;
while (!m_bExitThread) {
std::unique_lock<std::mutex> lk(m_mWatchdogMutex);

if (!m_bWillWatch)
m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified; });
else {
if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified; }) == false)
pthread_kill(m_iMainThreadPID, SIGUSR1);
}
m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified || m_bExitThread; });
else if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified || m_bExitThread; }) == false)
pthread_kill(m_iMainThreadPID, SIGUSR1);

if (m_bExitThread)
break;
Expand Down
9 changes: 5 additions & 4 deletions src/helpers/Watchdog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ class CWatchdog {
void startWatching();
void endWatching();

std::atomic<bool> m_bWatchdogInitialized{false};
private:
std::chrono::high_resolution_clock::time_point m_tTriggered;

pthread_t m_iMainThreadPID = 0;

bool m_bWatching = false;
bool m_bWillWatch = false;
std::atomic<bool> m_bWatching = false;
std::atomic<bool> m_bWillWatch = false;

std::unique_ptr<std::thread> m_pWatchdog;
std::mutex m_mWatchdogMutex;
bool m_bNotified = false;
bool m_bExitThread = false;
std::atomic<bool> m_bNotified = false;
std::atomic<bool> m_bExitThread = false;
std::condition_variable m_cvWatchdogCondition;
};

Expand Down

0 comments on commit 48fde62

Please sign in to comment.