CMS 3D CMS Logo

ThreadHandoff.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SimG4Core/Application
4 // Class : ThreadHandoff
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Christopher Jones
10 // Created: Mon, 16 Aug 2021 14:37:29 GMT
11 //
12 
13 // system include files
14 
15 // user include files
18 #include <array>
19 
20 //
21 // constants, enums and typedefs
22 //
23 
24 namespace {
25  std::string errorMessage(int erno) {
26  std::array<char, 1024> buffer;
27  strerror_r(erno, &buffer[0], buffer.size());
28  buffer.back() = '\0';
29  return std::string(&buffer[0]);
30  }
31 } // namespace
32 //
33 // static data member definitions
34 //
35 
36 //
37 // constructors and destructor
38 //
39 using namespace omt;
40 
42  pthread_attr_t attr;
43  int erno;
44  if (0 != (erno = pthread_attr_init(&attr))) {
45  throw cms::Exception("ThreadInitFailed")
46  << "Failed to initialize thread attributes (" << erno << ") " << errorMessage(erno);
47  }
48 
49  if (0 != (erno = pthread_attr_setstacksize(&attr, stackSize))) {
50  throw cms::Exception("ThreadStackSizeFailed")
51  << "Failed to set stack size " << stackSize << " " << errorMessage(erno);
52  }
53  std::unique_lock<std::mutex> lk(m_mutex);
54 
55  erno = pthread_create(&m_thread, &attr, threadLoop, this);
56  if (0 != erno) {
57  throw cms::Exception("ThreadCreateFailed") << " failed to create a pthread (" << erno << ") " << errorMessage(erno);
58  }
59  m_loopReady = false;
60  m_threadHandoff.wait(lk, [this]() { return m_loopReady; });
61 }
62 
63 // ThreadHandoff::ThreadHandoff(const ThreadHandoff& rhs)
64 // {
65 // // do actual copying here;
66 // }
67 
69  if (not m_stopThread) {
70  stopThread();
71  }
72  void* ret;
73  pthread_join(m_thread, &ret);
74 }
75 
76 //
77 // assignment operators
78 //
79 // const ThreadHandoff& ThreadHandoff::operator=(const ThreadHandoff& rhs)
80 // {
81 // //An exception safe implementation is
82 // ThreadHandoff temp(rhs);
83 // swap(rhs);
84 //
85 // return *this;
86 // }
87 
88 //
89 // member functions
90 //
91 
92 //
93 // const member functions
94 //
95 
96 //
97 // static member functions
98 //
99 void* ThreadHandoff::threadLoop(void* iArgs) {
100  auto theThis = reinterpret_cast<ThreadHandoff*>(iArgs);
101 
102  //need to hold lock until wait to avoid both threads
103  // being stuck in wait
104  std::unique_lock<std::mutex> lck(theThis->m_mutex);
105  theThis->m_loopReady = true;
106  theThis->m_threadHandoff.notify_one();
107 
108  do {
109  theThis->m_toRun = nullptr;
110  theThis->m_threadHandoff.wait(lck, [theThis]() { return nullptr != theThis->m_toRun; });
111  theThis->m_toRun->execute();
112  theThis->m_loopReady = true;
113  theThis->m_threadHandoff.notify_one();
114  } while (not theThis->m_stopThread);
115  theThis->m_loopReady = true;
116  return nullptr;
117 }
ThreadHandoff(int stackSize)
ret
prodAgent to be discontinued
std::condition_variable m_threadHandoff
Definition: ThreadHandoff.h:91
std::mutex m_mutex
Definition: ThreadHandoff.h:90
static void * threadLoop(void *iArgs)