ChimeraTK-DeviceAccess  03.18.00
ChimeraTK::async::DomainsContainer Class Reference

The DomainsContainer has a container with Domains and is performing actions on all of them. More...

#include <DomainsContainer.h>

+ Collaboration diagram for ChimeraTK::async::DomainsContainer:

Classes

class  StopThread
 

Public Member Functions

 ~DomainsContainer ()
 
void sendExceptions (const std::string &exceptionMessage)
 Request the sending of exceptions. More...
 
bool isSendingExceptions ()
 Check whether an exception distribution is started and not completed yet. More...
 
template<typename BackendType , typename BackendSpecificDataType , typename UserDataType >
boost::shared_ptr< AsyncNDRegisterAccessor< UserDataType > > subscribe (boost::shared_ptr< BackendType > backend, size_t domainId, bool activate, RegisterPath name, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
 Get an accessor from a particular domain. More...
 
boost::shared_ptr< DomaingetDomain (size_t key)
 Return the shared pointer to the Domain for a key. More...
 
void forEach (const std::function< void(size_t, boost::shared_ptr< Domain > &)> &executeMe)
 Iterate all Domains under the container lock. More...
 

Protected Member Functions

void distributeExceptions ()
 Endless loop executed in the thread. More...
 

Protected Attributes

std::atomic_bool _isSendingExceptions {false}
 
cppext::future_queue< std::string > _startExceptionDistribution {2}
 
std::thread _distributorThread
 
std::mutex _threadCreationMutex
 
std::atomic_bool _threadIsRunning {false}
 
std::mutex _domainsMutex
 
std::map< size_t, boost::weak_ptr< Domain > > _domains
 

Detailed Description

The DomainsContainer has a container with Domains and is performing actions on all of them.

The key type to identify the domain is of type size_t, which is the return type of std::hash, so you can easily use the hashes in case the backend uses a different key type.

Sending exceptions is implemented via a thread. sendExceptions() is pushing the exception message into a queue and returns immediately. A distributor thread is waiting for data in the queue and is sending the exceptions in all Domains.

The reason for having a thread is a possible lock order inversion. In the distribution tree, accessor creation must be mutually exclusibe with data distribution, hence locks cannot be avoided. As excaption can occur during data distribution. and backend::setException() is called, this would lead to recursive calls to the distribution tree, which might result in lock order inversions and deadlocks. To avoid this, setException will only put the exception message into the queue and return, allowing the failing distribution call to complete. The exception distribution will then be done by the thread in the DomainsContainer, after the mutex in the Domain is free again.

Definition at line 34 of file DomainsContainer.h.

Constructor & Destructor Documentation

◆ ~DomainsContainer()

ChimeraTK::async::DomainsContainer::~DomainsContainer ( )

Definition at line 41 of file DomainsContainer.cc.

Member Function Documentation

◆ distributeExceptions()

void ChimeraTK::async::DomainsContainer::distributeExceptions ( )
protected

Endless loop executed in the thread.

Definition at line 12 of file DomainsContainer.cc.

+ Here is the caller graph for this function:

◆ forEach()

void ChimeraTK::async::DomainsContainer::forEach ( const std::function< void(size_t, boost::shared_ptr< Domain > &)> &  executeMe)

Iterate all Domains under the container lock.

Each weak pointer is locked and the argument function is executed if the share_ptr is not nullptr.

The first parameter of the callback function is the domain key, the second a shared pointer to the domain itself.

Definition at line 91 of file DomainsContainer.cc.

+ Here is the caller graph for this function:

◆ getDomain()

boost::shared_ptr< Domain > ChimeraTK::async::DomainsContainer::getDomain ( size_t  key)

Return the shared pointer to the Domain for a key.

The shared pointer might be nullptr if locking of the weak pointer failed.

Definition at line 82 of file DomainsContainer.cc.

+ Here is the caller graph for this function:

◆ isSendingExceptions()

bool ChimeraTK::async::DomainsContainer::isSendingExceptions ( )
inline

Check whether an exception distribution is started and not completed yet.

Definition at line 45 of file DomainsContainer.h.

+ Here is the caller graph for this function:

◆ sendExceptions()

void ChimeraTK::async::DomainsContainer::sendExceptions ( const std::string &  exceptionMessage)

Request the sending of exceptions.

This function stores the request and returns immediately. The actual exception distribution is done asynchronously and has not necessarily finished when the function call returns. Use isSendingExceptions() to check whether the exception distribution has finished.

Definition at line 65 of file DomainsContainer.cc.

◆ subscribe()

template<typename BackendType , typename BackendSpecificDataType , typename UserDataType >
boost::shared_ptr< AsyncNDRegisterAccessor< UserDataType > > ChimeraTK::async::DomainsContainer::subscribe ( boost::shared_ptr< BackendType >  backend,
size_t  domainId,
bool  activate,
RegisterPath  name,
size_t  numberOfWords,
size_t  wordOffsetInRegister,
AccessModeFlags  flags 
)

Get an accessor from a particular domain.

At the moment the catalogue does not provide enough information to extract the domain ID from the register path. Hence the backend has to do it from its specific catalogue.

If the domain does not exist, it is created while holding the container lock.

The function is templated to three types. The first two parameters, backend type and a BackendSpecificDataType, are needed for the domain creation. The BackendSpecificDataType might vary for different Domains in the same backend. The UserDataType is the data type of the returned accessor.

The backend has to provide a function to get the initial value for that Domain.

template<typename BackendSpecificDataType>
std::pair<BackendSpecificUserType, VersionNumber> getAsyncDomainInitialValue(size_t asyncDomainId);

This function is returning the initial value for the domain with the according domainID. If the version number can be determined from the initial value data, the version number is set here. Otherwise the version number must be VersionNumber{nullptr}. If the version number cannot be determined from the initial value do not create a new version number here!. This must happen inside the Domain under the Domain lock to avoid race conditions.

Parameters for the async Domain creation:

Parameters
backendShared pointer to the exact backend type. As template functions cannot be virtual, we need a pointer of the type that implements getAsyncDomainInitialValue().
domainIdThe domainId is the key for the container (map).
activateFlag whether to activate the async domain if it is created.

Parameters for the actual accessor subscription:

Parameters
nameThe register path of the accessor
numberOfWordsEntries in the accessor
wordOffsetInRegisterAccessor starts at an offset
flagsThe access mode flags. They have to include wait_for_new_data.

Definition at line 122 of file DomainsContainer.h.

+ Here is the call graph for this function:

Member Data Documentation

◆ _distributorThread

std::thread ChimeraTK::async::DomainsContainer::_distributorThread
protected

Definition at line 109 of file DomainsContainer.h.

◆ _domains

std::map<size_t, boost::weak_ptr<Domain> > ChimeraTK::async::DomainsContainer::_domains
protected

Definition at line 116 of file DomainsContainer.h.

◆ _domainsMutex

std::mutex ChimeraTK::async::DomainsContainer::_domainsMutex
protected

Definition at line 115 of file DomainsContainer.h.

◆ _isSendingExceptions

std::atomic_bool ChimeraTK::async::DomainsContainer::_isSendingExceptions {false}
protected

Definition at line 103 of file DomainsContainer.h.

◆ _startExceptionDistribution

cppext::future_queue<std::string> ChimeraTK::async::DomainsContainer::_startExceptionDistribution {2}
protected

Definition at line 108 of file DomainsContainer.h.

◆ _threadCreationMutex

std::mutex ChimeraTK::async::DomainsContainer::_threadCreationMutex
protected

Definition at line 110 of file DomainsContainer.h.

◆ _threadIsRunning

std::atomic_bool ChimeraTK::async::DomainsContainer::_threadIsRunning {false}
protected

Definition at line 111 of file DomainsContainer.h.


The documentation for this class was generated from the following files: