From 18460a5aa0f46fbd2416d90fb04808c2a191c5f0 Mon Sep 17 00:00:00 2001
From: Julian Viereck <jviereck@tuebingen.mpg.de>
Date: Wed, 23 Sep 2020 14:28:39 +0200
Subject: [PATCH] Tracer: Adding lock to make it threadsafe

---
 include/dynamic-graph/tracer.h  | 2 ++
 src/traces/tracer-real-time.cpp | 1 +
 src/traces/tracer.cpp           | 9 +++++++++
 3 files changed, 12 insertions(+)

diff --git a/include/dynamic-graph/tracer.h b/include/dynamic-graph/tracer.h
index 9861b04..f5c23f2 100644
--- a/include/dynamic-graph/tracer.h
+++ b/include/dynamic-graph/tracer.h
@@ -8,6 +8,7 @@
 #include <boost/function.hpp>
 #include <list>
 #include <string>
+#include <mutex>
 
 #include <dynamic-graph/entity.h>
 #include <dynamic-graph/exception-traces.h>
@@ -27,6 +28,7 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
 protected:
   typedef std::list<const SignalBase<int> *> SignalList;
   SignalList toTraceSignals;
+  std::mutex files_mtx;
 
 public:
   enum TraceStyle {
diff --git a/src/traces/tracer-real-time.cpp b/src/traces/tracer-real-time.cpp
index ce7985d..70c4c12 100644
--- a/src/traces/tracer-real-time.cpp
+++ b/src/traces/tracer-real-time.cpp
@@ -146,6 +146,7 @@ void TracerRealTime::openFile(const SignalBase<int> &sig,
 
 void TracerRealTime::closeFiles() {
   dgDEBUGIN(15);
+  std::lock_guard<std::mutex> files_lock(files_mtx);
 
   FileList::iterator iter = files.begin();
   HardFileList::iterator hardIter = hardFiles.begin();
diff --git a/src/traces/tracer.cpp b/src/traces/tracer.cpp
index 99dadd7..e43df73 100644
--- a/src/traces/tracer.cpp
+++ b/src/traces/tracer.cpp
@@ -171,6 +171,7 @@ void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) {
 
 void Tracer::closeFiles() {
   dgDEBUGIN(15);
+  std::lock_guard<std::mutex> files_lock(files_mtx);
 
   for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
     std::ostream *filePtr = *iter;
@@ -193,6 +194,14 @@ void Tracer::record() {
 
   dgDEBUGIN(15);
 
+  // Ensure record() never hangs. If the attempt to acquire the lock fails,
+  // then closeFiles() is active and we shouldn't write to files anyways.
+  std::unique_lock<std::mutex> files_lock(files_mtx, std::try_to_lock);
+  if (!files_lock.owns_lock()) {
+    dgDEBUGOUT(15);
+    return;
+  }
+
   if (files.size() != toTraceSignals.size()) {
     DG_THROW
     ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing",
-- 
GitLab