diff --git a/include/dynamic-graph/tracer.h b/include/dynamic-graph/tracer.h index 9861b040b923bb829cbdbdcbcd140e064dfd1ef8..f5c23f265cdcde0a9593d512765a0668712cfe72 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 ce7985d4cccac9a8b52ef7367aff8898ac1d37ab..70c4c12ba1a0f568c3289f4bdf5e531fac50cd40 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 99dadd76ab170331d523c683615e27abb5f16221..e43df731d6a8d9b8010a835c65dda137dbefffd1 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",