Skip to content

Commit ad7d74e

Browse files
facontidavideclaude
andcommitted
Fix race condition in FileLogger2 constructor
The FileLogger2 constructor would start the writer thread after registering status change callbacks in the base class. This created a race condition where callbacks could fire before the writer thread was ready, causing TSAN failures (double lock and data race errors). Fix by adding an atomic 'ready' flag that is: - Set to true when the writer thread starts running - Checked in callback() before accessing the queue Callbacks that arrive before the writer thread is ready are now safely ignored. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2e54ffb commit ad7d74e

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

src/loggers/bt_file_logger_v2.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct FileLogger2::PImpl
2727

2828
std::thread writer_thread;
2929
std::atomic_bool loop = true;
30+
std::atomic_bool ready = false; // Set to true when writer thread is running
3031
};
3132

3233
FileLogger2::FileLogger2(const BT::Tree& tree, std::filesystem::path const& filepath)
@@ -84,6 +85,12 @@ FileLogger2::~FileLogger2()
8485
void FileLogger2::callback(Duration timestamp, const TreeNode& node,
8586
NodeStatus /*prev_status*/, NodeStatus status)
8687
{
88+
// Wait until the writer thread is ready to avoid race during construction
89+
if(!_p->ready.load(std::memory_order_acquire))
90+
{
91+
return;
92+
}
93+
8794
Transition trans{};
8895
trans.timestamp_usec = uint64_t(ToUsec(timestamp - _p->first_timestamp));
8996
trans.node_uid = node.UID();
@@ -102,6 +109,9 @@ void FileLogger2::flush()
102109

103110
void FileLogger2::writerLoop()
104111
{
112+
// Signal that the writer thread is ready to accept callbacks
113+
_p->ready.store(true, std::memory_order_release);
114+
105115
// local buffer in this thread
106116
std::deque<Transition> transitions;
107117

0 commit comments

Comments
 (0)