File indexing completed on 2024-04-06 12:30:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "SimG4Core/Application/interface/ThreadHandoff.h"
0017 #include "FWCore/Utilities/interface/Exception.h"
0018 #include <array>
0019
0020
0021
0022
0023
0024 namespace {
0025 std::string errorMessage(int erno) {
0026 std::array<char, 1024> buffer;
0027 strerror_r(erno, &buffer[0], buffer.size());
0028 buffer.back() = '\0';
0029 return std::string(&buffer[0]);
0030 }
0031 }
0032
0033
0034
0035
0036
0037
0038
0039 using namespace omt;
0040
0041 ThreadHandoff::ThreadHandoff(int stackSize) {
0042 pthread_attr_t attr;
0043 int erno;
0044 if (0 != (erno = pthread_attr_init(&attr))) {
0045 throw cms::Exception("ThreadInitFailed")
0046 << "Failed to initialize thread attributes (" << erno << ") " << errorMessage(erno);
0047 }
0048
0049 if (0 != (erno = pthread_attr_setstacksize(&attr, stackSize))) {
0050 throw cms::Exception("ThreadStackSizeFailed")
0051 << "Failed to set stack size " << stackSize << " " << errorMessage(erno);
0052 }
0053 std::unique_lock<std::mutex> lk(m_mutex);
0054
0055 erno = pthread_create(&m_thread, &attr, threadLoop, this);
0056 if (0 != erno) {
0057 throw cms::Exception("ThreadCreateFailed") << " failed to create a pthread (" << erno << ") " << errorMessage(erno);
0058 }
0059 m_loopReady = false;
0060 m_threadHandoff.wait(lk, [this]() { return m_loopReady; });
0061 }
0062
0063
0064
0065
0066
0067
0068 ThreadHandoff::~ThreadHandoff() {
0069 if (not m_stopThread) {
0070 stopThread();
0071 }
0072 void* ret;
0073 pthread_join(m_thread, &ret);
0074 }
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 void* ThreadHandoff::threadLoop(void* iArgs) {
0100 auto theThis = reinterpret_cast<ThreadHandoff*>(iArgs);
0101
0102
0103
0104 std::unique_lock<std::mutex> lck(theThis->m_mutex);
0105 theThis->m_loopReady = true;
0106 theThis->m_threadHandoff.notify_one();
0107
0108 do {
0109 theThis->m_toRun = nullptr;
0110 theThis->m_threadHandoff.wait(lck, [theThis]() { return nullptr != theThis->m_toRun; });
0111 theThis->m_toRun->execute();
0112 theThis->m_loopReady = true;
0113 theThis->m_threadHandoff.notify_one();
0114 } while (not theThis->m_stopThread);
0115 theThis->m_loopReady = true;
0116 return nullptr;
0117 }