Here I'm using compare_exchange to grab the queue exclusively (swapping with a nullptr) when pushing a message, in a way that it can't be deallocated.
When deallocating, the thread that wants to do so first waits for the consumer thread to stop, by joining, and then synchronizes with the real-time audio thread by grabbing the queue itself (same way, by setting to nullptr). At this point, the real-time audio thread starts dropping the messages on the floor (or has already observered that logging has been disabled, so doesn't log).
We can then proceed with the deallocation.
I've added a stress-test that has found a bunch of issues while running for longs periods of time, and now runs without issues under ASAN and TSAN, on x86_64.
Turns out the previous code wasn't safe.
Here I'm using
compare_exchange
to grab the queue exclusively (swapping with anullptr
) when pushing a message, in a way that it can't be deallocated.When deallocating, the thread that wants to do so first waits for the consumer thread to stop, by joining, and then synchronizes with the real-time audio thread by grabbing the queue itself (same way, by setting to
nullptr
). At this point, the real-time audio thread starts dropping the messages on the floor (or has already observered that logging has been disabled, so doesn't log).We can then proceed with the deallocation.
I've added a stress-test that has found a bunch of issues while running for longs periods of time, and now runs without issues under ASAN and TSAN, on x86_64.