CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
19 //
20 // constants, enums and typedefs
21 //
22 
23 namespace {
24  std::string errorMessage(int erno) {
25  std::array<char, 1024> buffer;
26  strerror_r(erno, &buffer[0], buffer.size());
27  buffer.back() = '\0';
28  return std::string(&buffer[0]);
29  }
30 } // namespace
31 //
32 // static data member definitions
33 //
34 
35 //
36 // constructors and destructor
37 //
38 using namespace omt;
39 
41  pthread_attr_t attr;
42  int erno;
43  if (0 != (erno = pthread_attr_init(&attr))) {
44  throw cms::Exception("ThreadInitFailed")
45  << "Failed to initialize thread attributes (" << erno << ") " << errorMessage(erno);
46  }
47 
48  if (0 != (erno = pthread_attr_setstacksize(&attr, stackSize))) {
49  throw cms::Exception("ThreadStackSizeFailed")
50  << "Failed to set stack size " << stackSize << " " << errorMessage(erno);
51  }
52  std::unique_lock<std::mutex> lk(m_mutex);
53 
54  erno = pthread_create(&m_thread, &attr, threadLoop, this);
55  if (0 != erno) {
56  throw cms::Exception("ThreadCreateFailed") << " failed to create a pthread (" << erno << ") " << errorMessage(erno);
57  }
58  m_loopReady = false;
59  m_threadHandoff.wait(lk, [this]() { return m_loopReady; });
60 }
61 
62 // ThreadHandoff::ThreadHandoff(const ThreadHandoff& rhs)
63 // {
64 // // do actual copying here;
65 // }
66 
68  if (not m_stopThread) {
69  stopThread();
70  }
71  void* ret;
72  pthread_join(m_thread, &ret);
73 }
74 
75 //
76 // assignment operators
77 //
78 // const ThreadHandoff& ThreadHandoff::operator=(const ThreadHandoff& rhs)
79 // {
80 // //An exception safe implementation is
81 // ThreadHandoff temp(rhs);
82 // swap(rhs);
83 //
84 // return *this;
85 // }
86 
87 //
88 // member functions
89 //
90 
91 //
92 // const member functions
93 //
94 
95 //
96 // static member functions
97 //
98 void* ThreadHandoff::threadLoop(void* iArgs) {
99  auto theThis = reinterpret_cast<ThreadHandoff*>(iArgs);
100 
101  //need to hold lock until wait to avoid both threads
102  // being stuck in wait
103  std::unique_lock<std::mutex> lck(theThis->m_mutex);
104  theThis->m_loopReady = true;
105  theThis->m_threadHandoff.notify_one();
106 
107  do {
108  theThis->m_toRun = nullptr;
109  theThis->m_threadHandoff.wait(lck, [theThis]() { return nullptr != theThis->m_toRun; });
110  theThis->m_toRun->execute();
111  theThis->m_loopReady = true;
112  theThis->m_threadHandoff.notify_one();
113  } while (not theThis->m_stopThread);
114  theThis->m_loopReady = true;
115  return nullptr;
116 }
ThreadHandoff(int stackSize)
tuple 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)