rippled
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ripple::ClosureCounter< Ret_t, Args_t > Class Template Reference

The role of a ClosureCounter is to assist in shutdown by letting callers wait for the completion of closures (of a specific type signature) that they previously registered. More...

Collaboration diagram for ripple::ClosureCounter< Ret_t, Args_t >:
Collaboration graph
[legend]

Classes

class  Substitute
 

Public Member Functions

 ClosureCounter ()=default
 
 ClosureCounter (ClosureCounter const &)=delete
 
ClosureCounteroperator= (ClosureCounter const &)=delete
 
 ~ClosureCounter ()
 Destructor verifies all in-flight closures are complete. More...
 
void join (char const *name, std::chrono::milliseconds wait, beast::Journal j)
 Returns once all counted in-flight closures are destroyed. More...
 
template<class Closure >
std::optional< Substitute< Closure > > wrap (Closure &&closure)
 Wrap the passed closure with a reference counter. More...
 
int count () const
 Current number of Closures outstanding. More...
 
bool joined () const
 Returns true if this has been joined. More...
 

Private Member Functions

ClosureCounteroperator++ ()
 
ClosureCounteroperator-- ()
 

Private Attributes

std::mutex mutex_ {}
 
std::condition_variable allClosuresDoneCond_ {}
 
bool waitForClosures_ {false}
 
std::atomic< int > closureCount_ {0}
 

Detailed Description

template<typename Ret_t, typename... Args_t>
class ripple::ClosureCounter< Ret_t, Args_t >

The role of a ClosureCounter is to assist in shutdown by letting callers wait for the completion of closures (of a specific type signature) that they previously registered.

These closures are typically callbacks for asynchronous operations. The lifetime of a ClosureCounter consists of two phases: the initial expanding "fork" phase, and the subsequent shrinking "join" phase.

In the fork phase, callers register a closure by passing the closure and receiving a substitute in return. The substitute has the same callable interface as the closure, and it informs the ClosureCounter whenever it is copied or destroyed, so that it can keep an accurate count of copies.

The transition to the join phase is made by a call to join. In this phase, every substitute returned going forward will be null, signaling to the caller that they should drop the closure and cancel their operation. join blocks until all existing closure substitutes are destroyed.

Template Parameters
Ret_tThe return type of the closure.
Args_tThe argument types of the closure.

Definition at line 54 of file ClosureCounter.h.

Constructor & Destructor Documentation

◆ ClosureCounter() [1/2]

template<typename Ret_t , typename... Args_t>
ripple::ClosureCounter< Ret_t, Args_t >::ClosureCounter ( )
default

◆ ClosureCounter() [2/2]

template<typename Ret_t , typename... Args_t>
ripple::ClosureCounter< Ret_t, Args_t >::ClosureCounter ( ClosureCounter< Ret_t, Args_t > const &  )
delete

◆ ~ClosureCounter()

template<typename Ret_t , typename... Args_t>
ripple::ClosureCounter< Ret_t, Args_t >::~ClosureCounter ( )

Destructor verifies all in-flight closures are complete.

Definition at line 153 of file ClosureCounter.h.

Member Function Documentation

◆ operator++()

template<typename Ret_t , typename... Args_t>
ClosureCounter& ripple::ClosureCounter< Ret_t, Args_t >::operator++ ( )
private

Definition at line 64 of file ClosureCounter.h.

◆ operator--()

template<typename Ret_t , typename... Args_t>
ClosureCounter& ripple::ClosureCounter< Ret_t, Args_t >::operator-- ( )
private

Definition at line 73 of file ClosureCounter.h.

◆ operator=()

template<typename Ret_t , typename... Args_t>
ClosureCounter& ripple::ClosureCounter< Ret_t, Args_t >::operator= ( ClosureCounter< Ret_t, Args_t > const &  )
delete

◆ join()

template<typename Ret_t , typename... Args_t>
void ripple::ClosureCounter< Ret_t, Args_t >::join ( char const *  name,
std::chrono::milliseconds  wait,
beast::Journal  j 
)

Returns once all counted in-flight closures are destroyed.

Parameters
nameName reported if join time exceeds wait.
waitIf join() exceeds this duration report to Journal.
jJournal written to if wait is exceeded.

Definition at line 166 of file ClosureCounter.h.

◆ wrap()

template<typename Ret_t , typename... Args_t>
template<class Closure >
std::optional<Substitute<Closure> > ripple::ClosureCounter< Ret_t, Args_t >::wrap ( Closure &&  closure)

Wrap the passed closure with a reference counter.

Parameters
closureClosure that accepts Args_t parameters and returns Ret_t.
Returns
If join() has been called returns std::nullopt. Otherwise returns a std::optional that wraps closure with a reference counter.

Definition at line 192 of file ClosureCounter.h.

◆ count()

template<typename Ret_t , typename... Args_t>
int ripple::ClosureCounter< Ret_t, Args_t >::count ( ) const

Current number of Closures outstanding.

Only useful for testing.

Definition at line 205 of file ClosureCounter.h.

◆ joined()

template<typename Ret_t , typename... Args_t>
bool ripple::ClosureCounter< Ret_t, Args_t >::joined ( ) const

Returns true if this has been joined.

Even if true is returned, counted closures may still be in flight. However if (joined() && (count() == 0)) there should be no more counted closures in flight.

Definition at line 217 of file ClosureCounter.h.

Member Data Documentation

◆ mutex_

template<typename Ret_t , typename... Args_t>
std::mutex ripple::ClosureCounter< Ret_t, Args_t >::mutex_ {}
mutableprivate

Definition at line 57 of file ClosureCounter.h.

◆ allClosuresDoneCond_

template<typename Ret_t , typename... Args_t>
std::condition_variable ripple::ClosureCounter< Ret_t, Args_t >::allClosuresDoneCond_ {}
private

Definition at line 58 of file ClosureCounter.h.

◆ waitForClosures_

template<typename Ret_t , typename... Args_t>
bool ripple::ClosureCounter< Ret_t, Args_t >::waitForClosures_ {false}
private

Definition at line 59 of file ClosureCounter.h.

◆ closureCount_

template<typename Ret_t , typename... Args_t>
std::atomic<int> ripple::ClosureCounter< Ret_t, Args_t >::closureCount_ {0}
private

Definition at line 60 of file ClosureCounter.h.