Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/wolfpld/tracy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Jacob <benoitjacob@google.com>2022-04-12 20:33:47 +0300
committerBenoit Jacob <benoitjacob@google.com>2022-04-12 20:34:41 +0300
commit55ae38a13867680d567872e9de1c9fe26bd9d802 (patch)
treea179c6699e60499987133e2adb88608db346f43d /capture
parent8c3868e43b4f65e602dee19e40371c313b934e7d (diff)
Make disconnect atomic because it's written by a signal handler
Diffstat (limited to 'capture')
-rw-r--r--capture/src/capture.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/capture/src/capture.cpp b/capture/src/capture.cpp
index 94afe036..9f92dad7 100644
--- a/capture/src/capture.cpp
+++ b/capture/src/capture.cpp
@@ -4,6 +4,7 @@
# include <unistd.h>
#endif
+#include <atomic>
#include <chrono>
#include <inttypes.h>
#include <mutex>
@@ -25,11 +26,19 @@
#endif
-volatile bool disconnect = false;
+// This atomic is written by a signal handler (SigInt). Traditionally that would
+// have had to be `volatile sig_atomic_t`, and annoyingly, `bool` was
+// technically not allowed there, even though in practice it would work.
+// The good thing with C++11 atomics is that we can use atomic<bool> instead
+// here and be on the actually supported path.
+std::atomic<bool> disconnect;
void SigInt( int )
{
- disconnect = true;
+ // Relaxed order is closest to a traditional `volatile` write.
+ // We don't need stronger ordering since this signal handler doesn't do
+ // anything else that would need to be ordered relatively to this.
+ disconnect.store(true, std::memory_order_relaxed);
}
[[noreturn]] void Usage()
@@ -137,10 +146,15 @@ int main( int argc, char** argv )
const auto t0 = std::chrono::high_resolution_clock::now();
while( worker.IsConnected() )
{
- if( disconnect )
+ // Relaxed order is sufficient here because `disconnect` is only ever
+ // set by this thread or by the SigInt handler, and that handler does
+ // nothing else than storing `disconnect`.
+ if( disconnect.load( std::memory_order_relaxed ) )
{
worker.Disconnect();
- disconnect = false;
+ // Relaxed order is sufficient because only this thread ever reads
+ // this value.
+ disconnect.store(false, std::memory_order_relaxed );
break;
}
@@ -172,7 +186,9 @@ int main( int argc, char** argv )
const auto dur = std::chrono::high_resolution_clock::now() - t0;
if( std::chrono::duration_cast<std::chrono::seconds>(dur).count() >= seconds )
{
- disconnect = true;
+ // Relaxed order is sufficient because only this thread ever reads
+ // this value.
+ disconnect.store(true, std::memory_order_relaxed );
}
}
}