11#ifndef __AUDACITY_MESSAGE_BUFFER__
12#define __AUDACITY_MESSAGE_BUFFER__
22template<
typename Data>
26 std::atomic<bool>
mBusy{
false };
39 template<
typename Result = Data,
typename... ConstructorArgs>
43 template<
typename Arg = Data&&>
void Write( Arg &&arg );
46template<
typename Data>
49 for (
auto &slot : mSlots)
51 while ( slot.mBusy.exchange(
true, std::memory_order_acquire ) )
56 mLastWrittenSlot.store( 0, std::memory_order_relaxed );
58 for (
auto &slot : mSlots)
59 slot.mBusy.exchange(
false, std::memory_order_release );
62template<
typename Data>
63template<
typename Result,
typename... ConstructorArgs>
67 auto idx = mLastWrittenSlot.load( std::memory_order_relaxed );
74 wasBusy = mSlots[idx].mBusy.exchange(
true, std::memory_order_acquire );
79 std::move( mSlots[idx].mData ), std::forward<ConstructorArgs>(args)... );
81 mSlots[idx].mBusy.store(
false, std::memory_order_release );
86template<
typename Data>
91 auto idx = mLastWrittenSlot.load( std::memory_order_relaxed );
97 wasBusy = mSlots[idx].mBusy.exchange(
true, std::memory_order_acquire );
100 mSlots[idx].mData = std::forward<Arg>(arg);
101 mLastWrittenSlot.store( idx, std::memory_order_relaxed );
103 mSlots[idx].mBusy.store(
false, std::memory_order_release );
Communicate data atomically from one writer thread to one reader.
Result Read(ConstructorArgs &&...args)
Move data out (if available), or else copy it out.
NonInterfering< UpdateSlot > mSlots[2]
void Write(Arg &&arg)
Reassign a slot by move or copy.
std::atomic< unsigned char > mLastWrittenSlot
std::atomic< bool > mBusy