forked from Alepha/Alepha
Non-blocking states and documentation for Interlock.
This commit is contained in:
32
Thread.cc
32
Thread.cc
@ -9,10 +9,18 @@ static_assert( __cplusplus > 2020'99 );
|
||||
#include <Alepha/Utility/StaticValue.h>
|
||||
#include <Alepha/Utility/evaluation_helpers.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
namespace Alepha::Hydrogen::detail::Thread_m
|
||||
{
|
||||
namespace
|
||||
{
|
||||
namespace C
|
||||
{
|
||||
const bool debug= false;
|
||||
const bool debugWaiters= false or C::debug;
|
||||
}
|
||||
|
||||
struct ThreadState
|
||||
{
|
||||
std::mutex access;
|
||||
@ -105,6 +113,7 @@ namespace Alepha::Hydrogen::detail::Thread_m
|
||||
struct Interlock::Impl
|
||||
{
|
||||
State state= Open;
|
||||
bool threadBlocked= false;
|
||||
|
||||
ConditionVariable var;
|
||||
};
|
||||
@ -143,6 +152,7 @@ namespace Alepha::Hydrogen::detail::Thread_m
|
||||
if( impl().state == Waiting )
|
||||
{
|
||||
// Nolock form will just leave the bit set.
|
||||
assert( not impl().threadBlocked );
|
||||
}
|
||||
else if( impl().state == Synchronizing )
|
||||
{
|
||||
@ -157,21 +167,35 @@ namespace Alepha::Hydrogen::detail::Thread_m
|
||||
{
|
||||
if( impl().state == Waiting )
|
||||
{
|
||||
impl().threadBlocked= true;
|
||||
while( impl().state == Waiting )
|
||||
{
|
||||
impl().var.wait( lock );
|
||||
}
|
||||
assert( not impl().threadBlocked );
|
||||
impl().state= Open;
|
||||
impl().var.notify_one();
|
||||
}
|
||||
else if( impl().state == Synchronizing )
|
||||
{
|
||||
impl().state= Opening;
|
||||
impl().var.notify_one();
|
||||
|
||||
while( impl().state == Opening )
|
||||
const bool unblock= impl().threadBlocked;
|
||||
impl().threadBlocked= false;
|
||||
if( unblock )
|
||||
{
|
||||
impl().var.wait( lock );
|
||||
impl().var.notify_one();
|
||||
|
||||
while( impl().state == Opening )
|
||||
{
|
||||
impl().var.wait( lock );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( C::debugWaiters )
|
||||
{
|
||||
error() << "Not waiting on other side, as nobody's there." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{ abort(); }
|
||||
|
||||
Reference in New Issue
Block a user