forked from Alepha/Alepha
Add notification primitive to Mailbox.
This commit is contained in:
@ -13,6 +13,7 @@ static_assert( __cplusplus > 2020'99 );
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
|
||||
#include <Alepha/Thread.h>
|
||||
#include <Alepha/Exception.h>
|
||||
@ -95,6 +96,8 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
std::vector< Item > filled;
|
||||
std::vector< Item >::iterator pos= begin( filled );
|
||||
|
||||
std::exception_ptr notification;
|
||||
|
||||
bool finished= false;
|
||||
|
||||
bool mustFinish= false;
|
||||
@ -125,6 +128,15 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
interlockPoint.checkpoint( lock, [&]{ awaken( lock ); } );
|
||||
}
|
||||
|
||||
[[noreturn]] void
|
||||
raiseNotification()
|
||||
{
|
||||
auto notification_ptr= std::move( notification );
|
||||
notification= nullptr;
|
||||
std::rethrow_exception( std::move( notification_ptr ) );
|
||||
abort();
|
||||
}
|
||||
|
||||
[[noreturn]] void
|
||||
raiseFinished()
|
||||
{
|
||||
@ -163,10 +175,12 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
if( pos == end( filled ) ) [[unlikely]]
|
||||
{
|
||||
if( C::debugPop ) error() << "We might have to hit the sync point." << std::endl;
|
||||
if( notification ) raiseNotification();
|
||||
if( mustFinish ) raiseFinished();
|
||||
Alepha::unique_lock lock( access );
|
||||
if( C::debugPop ) error() << "We have to hit the sync point." << std::endl;
|
||||
interlock( lock );
|
||||
if( notification and pos == end( filled ) ) raiseNotification();
|
||||
if( finished )
|
||||
{
|
||||
if( pos == end( filled ) ) raiseFinished();
|
||||
@ -224,6 +238,21 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
finished= true;
|
||||
checkpoint( lock );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief This function will pump the mailbox, and deliver a custom notification
|
||||
* event to the other side.
|
||||
*/
|
||||
void
|
||||
notify( auto newNotification )
|
||||
{
|
||||
auto notification_ptr= std::make_exception_ptr( std::move( notification ) );
|
||||
Alepha::unique_lock lock( access );
|
||||
assertion( not finished );
|
||||
notification= std::move( notification_ptr );
|
||||
interlock( lock );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user