ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
DomainsContainer.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
5
6#include "Exception.h"
7
8namespace ChimeraTK::async {
9
10 /********************************************************************************************************************/
11
13 std::string exceptionMessage;
14 while(true) {
15 // block to wait until setException has been called
16 try {
17 _startExceptionDistribution.pop_wait(exceptionMessage);
18 }
19 catch(StopThread&) {
20 return;
21 }
22
23 auto ex = std::make_exception_ptr(ChimeraTK::runtime_error(exceptionMessage));
24
25 {
26 std::lock_guard<std::mutex> containerLock(_domainsMutex);
27 for(auto& keyAndDomain : _domains) {
28 auto domain = keyAndDomain.second.lock();
29 if(domain) {
30 domain->sendException(ex);
31 }
32 }
33 } // lock scope
34
36 }
37 }
38
39 /********************************************************************************************************************/
40
42 try {
43 auto threadCreationLock = std::lock_guard(_threadCreationMutex);
44
45 if(_distributorThread.joinable()) {
46 _startExceptionDistribution.push_overwrite_exception(std::make_exception_ptr(StopThread{}));
47 // Now we can join the thread.
48 _distributorThread.join();
49 }
50 }
51 catch(std::system_error& e) {
52 // Destructors must not throw. All exceptions that can occur here are system errors, which only show up if there
53 // is no hope anyway. All we can do is terminate.
54 std::cerr << "Unrecoverable system error in ~DomainsContainer(): " << e.what() << " !!! TERMINATING !!!"
55 << std::endl;
56 std::terminate();
57 }
58
59 // Unblock a potentially waiting open call
61 }
62
63 /********************************************************************************************************************/
64
65 void DomainsContainer::sendExceptions(const std::string& exceptionMessage) {
67 throw ChimeraTK::logic_error("DomainsContainer::sendExceptions() called before previous distribution was ready.");
68 }
69
70 if(!_threadIsRunning) {
71 // No subscribers yet. Don't write anything into the queue.
72 return;
73 }
74
76
77 _startExceptionDistribution.push(exceptionMessage);
78 }
79
80 /********************************************************************************************************************/
81
82 boost::shared_ptr<Domain> DomainsContainer::getDomain(size_t key) {
83 std::lock_guard<std::mutex> domainsLock(_domainsMutex);
84 // Creates the entry if it is not there. The returned shared pointer is empty in this case.
85 // (It might also be empty if the entry exists, but the async domain was deleted.)
86 return _domains[key].lock();
87 }
88
89 /********************************************************************************************************************/
90
91 void DomainsContainer::forEach(const std::function<void(size_t, boost::shared_ptr<Domain>&)>& executeMe) {
92 std::lock_guard<std::mutex> domainsLock(_domainsMutex);
93 for(auto& keyAndDomain : _domains) {
94 auto domain = keyAndDomain.second.lock();
95 if(domain) {
96 executeMe(keyAndDomain.first, domain);
97 }
98 }
99 }
100
101} // namespace ChimeraTK::async
std::map< size_t, boost::weak_ptr< Domain > > _domains
cppext::future_queue< std::string > _startExceptionDistribution
void sendExceptions(const std::string &exceptionMessage)
Request the sending of exceptions.
void forEach(const std::function< void(size_t, boost::shared_ptr< Domain > &)> &executeMe)
Iterate all Domains under the container lock.
boost::shared_ptr< Domain > getDomain(size_t key)
Return the shared pointer to the Domain for a key.
void distributeExceptions()
Endless loop executed in the thread.
Exception thrown when a logic error has occured.
Definition Exception.h:51
Exception thrown when a runtime error has occured.
Definition Exception.h:18