static_assert( __cplusplus > 2020'99 ); #pragma once #include #include #include #include #include namespace Alepha::Hydrogen::Atomic ::detail:: DeadDrop_m { inline namespace exports { template< typename Item > class DeadDrop; } template< typename Item > class exports::DeadDrop { private: Alepha::mutex access; struct Box { private: Alepha::mutex *access= nullptr; Alepha::condition_variable ready; Item original; Item *active= &original; boost::circular_buffer< Item * > next{ 2 }; Box *companion= nullptr; friend DeadDrop; void setup( Alepha::mutex *const access, Box *const companion ) { this->access= access; this->companion= companion; } public: Item & acquireBox() { if( not active ) { [[unlikely]]; std::unique_lock lock{ *access }; ready.wait( lock, [&]{ return not next.empty(); } ); active= next.front(); next.pop_front(); } assert( active ); return *active; } void releaseBox() { std::unique_lock lock{ *access }; companion->next.push_back( active ); active= nullptr; companion->ready.notify_one(); } }; public: Box producer; Box consumer; explicit DeadDrop() { producer.setup( &this->access, &consumer ); consumer.setup( &this->access, &producer ); } }; } namespace Alepha::Hydrogen::Atomic::inline exports::inline DeadDrop_m { using namespace detail::DeadDrop_m::exports; }