[Libreoffice-commits] online.git: common/SigUtil.cpp common/SigUtil.hpp kit/Kit.cpp
Ashod Nakashian (via logerrit)
logerrit at kemper.freedesktop.org
Tue Nov 19 15:12:47 UTC 2019
common/SigUtil.cpp | 43 ++++++++++++++++++++++++++++++++++++++-----
common/SigUtil.hpp | 12 +++++-------
kit/Kit.cpp | 5 ++---
3 files changed, 45 insertions(+), 15 deletions(-)
New commits:
commit b74306acd5c833363cf6c116913c134bb02ddac1
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Mon Nov 18 09:12:30 2019 -0500
Commit: Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Tue Nov 19 16:12:29 2019 +0100
wsd: replace mutex in signal handler
There are a few things acceptable/safe in a
signal handler, and taking locks is not one of them.
This replaces the logic with a simple counter that
serves the purpose just as well.
If we get a double signal, we log and ignore.
Change-Id: If589c18492468c120d00c213805467bcbba05d27
Reviewed-on: https://gerrit.libreoffice.org/83150
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/common/SigUtil.cpp b/common/SigUtil.cpp
index be626ff6b..e5dabcb6f 100644
--- a/common/SigUtil.cpp
+++ b/common/SigUtil.cpp
@@ -83,13 +83,38 @@ namespace SigUtil
}
#if !MOBILEAPP
-std::mutex SigHandlerTrap;
-
namespace SigUtil
{
- std::mutex& getSigHandlerTrap()
+ /// This traps the signal-handler so we don't _Exit
+ /// while dumping stack trace. It's re-entrant.
+ /// Used to safely increment and decrement the signal-handler trap.
+ class SigHandlerTrap
+ {
+ static std::atomic<int> SigHandling;
+ public:
+ SigHandlerTrap() { ++SigHandlerTrap::SigHandling; }
+ ~SigHandlerTrap() { --SigHandlerTrap::SigHandling; }
+
+ /// Check that we have exclusive access to the trap.
+ /// Otherwise, there is another signal in progress.
+ bool isExclusive() const
+ {
+ // Return true if we are alone.
+ return SigHandlerTrap::SigHandling == 1;
+ }
+
+ /// Wait for the trap to clear.
+ static void wait()
+ {
+ while (SigHandlerTrap::SigHandling)
+ sleep(1);
+ }
+ };
+ std::atomic<int> SigHandlerTrap::SigHandling;
+
+ void waitSigHandlerTrap()
{
- return SigHandlerTrap;
+ SigHandlerTrap::wait();
}
const char *signalName(const int signo)
@@ -211,7 +236,15 @@ namespace SigUtil
static
void handleFatalSignal(const int signal)
{
- std::unique_lock<std::mutex> lock(SigHandlerTrap);
+ SigHandlerTrap guard;
+ if (!guard.isExclusive())
+ {
+ Log::signalLogPrefix();
+ Log::signalLog(" Fatal double signal received: ");
+ Log::signalLog(signalName(signal));
+ Log::signalLog("\n Already handling a signal; will ignore this.");
+ return;
+ }
Log::signalLogPrefix();
Log::signalLog(" Fatal signal received: ");
diff --git a/common/SigUtil.hpp b/common/SigUtil.hpp
index caf8d531d..95371f3a1 100644
--- a/common/SigUtil.hpp
+++ b/common/SigUtil.hpp
@@ -38,14 +38,12 @@ namespace SigUtil
bool getDumpGlobalState();
/// Reset the flag to dump internal state.
void resetDumpGlobalState();
-}
#if !MOBILEAPP
-namespace SigUtil
-{
- /// Mutex to trap signal handler, if any,
+
+ /// Wait for the signal handler, if any,
/// and prevent _Exit while collecting backtrace.
- std::mutex& getSigHandlerTrap();
+ void waitSigHandlerTrap();
/// Returns the name of the signal.
const char* signalName(int signo);
@@ -78,10 +76,10 @@ namespace SigUtil
/// Dump a signal-safe back-trace
void dumpBacktrace();
-} // end namespace SigUtil
-
#endif // !MOBILEAPP
+} // end namespace SigUtil
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index d04277bf8..101a40445 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -2641,11 +2641,10 @@ void lokit_main(
#if !MOBILEAPP
- // Trap the signal handler, if invoked,
- // to prevent exiting.
LOG_INF("Process finished.");
Log::shutdown();
- std::unique_lock<std::mutex> lock(SigUtil::getSigHandlerTrap());
+ // Wait for the signal handler, if invoked, to prevent exiting until done.
+ SigUtil::waitSigHandlerTrap();
std::_Exit(EX_OK);
#endif
More information about the Libreoffice-commits
mailing list