From 5eaa7c0834859f83dd40b2eb19f0e57bea80285f Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:54:34 +0100 Subject: [PATCH] core: terminate the poll thread (#150) * core: terminate the poll thread * core: use sigaction instead of signal * core: use VA_RESTART for the unlock signal --- src/core/hyprlock.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/hyprlock.cpp b/src/core/hyprlock.cpp index e14b74b..ee961c3 100644 --- a/src/core/hyprlock.cpp +++ b/src/core/hyprlock.cpp @@ -34,7 +34,7 @@ CHyprlock::CHyprlock(const std::string& wlDisplay, const bool immediate) { const auto GRACE = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:grace"); m_tGraceEnds = **GRACE ? std::chrono::system_clock::now() + std::chrono::seconds(**GRACE) : std::chrono::system_clock::from_time_t(0); } else { - m_tGraceEnds = std::chrono::system_clock::from_time_t(0); + m_tGraceEnds = std::chrono::system_clock::from_time_t(0); } } @@ -292,6 +292,14 @@ void CHyprlock::onGlobalRemoved(void* data, struct wl_registry* registry, uint32 // end wl_registry +static void registerSignalAction(int sig, void (*handler)(int), int sa_flags = 0) { + struct sigaction sa; + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = sa_flags; + sigaction(sig, &sa, NULL); +} + static void handleUnlockSignal(int sig) { if (sig == SIGUSR1) { Debug::log(LOG, "Unlocking with a SIGUSR1"); @@ -299,6 +307,10 @@ static void handleUnlockSignal(int sig) { } } +static void handlePollTerminate(int sig) { + ; +} + static void handleCriticalSignal(int sig) { g_pHyprlock->attemptRestoreOnDeath(); abort(); @@ -342,9 +354,10 @@ void CHyprlock::run() { lockSession(); - signal(SIGUSR1, handleUnlockSignal); - signal(SIGSEGV, handleCriticalSignal); - signal(SIGABRT, handleCriticalSignal); + registerSignalAction(SIGUSR1, handleUnlockSignal, SA_RESTART); + registerSignalAction(SIGUSR2, handlePollTerminate); + registerSignalAction(SIGSEGV, handleCriticalSignal); + registerSignalAction(SIGABRT, handleCriticalSignal); pollfd pollfds[] = { { @@ -355,7 +368,7 @@ void CHyprlock::run() { std::thread pollThr([this, &pollfds]() { while (!m_bTerminate) { - int ret = poll(pollfds, 1, 5000 /* 5 seconds, reasonable. It's because we might need to terminate */); + int ret = poll(pollfds, 1, 5000 /* 5 seconds, reasonable. Just in case we need to terminate and the signal fails */); if (ret < 0) { Debug::log(CRIT, "[core] Polling fds failed with {}", errno); @@ -477,6 +490,8 @@ void CHyprlock::run() { wl_display_disconnect(m_sWaylandState.display); + pthread_kill(pollThr.native_handle(), SIGUSR2); + // wait for threads to exit cleanly to avoid a coredump pollThr.join(); timersThr.join(); @@ -922,4 +937,4 @@ void CHyprlock::attemptRestoreOnDeath() { spawnSync("hyprctl keyword misc:allow_session_lock_restore true"); spawnAsync("sleep 2 && hyprlock & disown"); -} \ No newline at end of file +}