Belle II Software  release-05-02-19
PThread.h
1 #ifndef _Belle2_PThread_hh
2 #define _Belle2_PThread_hh
3 
4 #include <daq/slc/system/LogFile.h>
5 
6 #include <pthread.h>
7 #include <signal.h>
8 #include <cstdio>
9 
10 namespace Belle2 {
16  class PThread {
17 
18  private:
19  template<class WORKER>
20  static void destroy(void* arg)
21  {
22  WORKER* worker = (WORKER*)arg;
23  delete worker;
24  worker = NULL;
25  }
26  template<class WORKER>
27  static void* create_destroy(void* arg)
28  {
29  WORKER* worker = (WORKER*)arg;
30  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
31  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
32  pthread_cleanup_push(PThread::destroy<WORKER>, arg);
33  try {
34  worker->run();
35  } catch (const std::exception& e) {
36  LogFile::fatal(e.what());
37  }
38  pthread_cleanup_pop(1);
39  return NULL;
40  }
41  template<class WORKER>
42  static void* create(void* arg)
43  {
44  WORKER* worker = (WORKER*)arg;
45  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
46  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
47  try {
48  worker->run();
49  } catch (const std::exception& e) {
50  LogFile::fatal(e.what());
51  }
52  return NULL;
53  }
54 
55  public:
56  static void exit() { pthread_exit(NULL); }
57 
58  public:
59  PThread() : m_th(0) {}
60  template<class WORKER>
61  PThread(WORKER* worker, bool destroyed = true, bool detached = true, std::string thread_name = "")
62  {
63  m_th = 0;
64  if (destroyed) {
65  if (pthread_create(&m_th, NULL, PThread::create_destroy<WORKER>,
66  (void*)worker) != 0) {
67  m_th = 0;
68  }
69  } else {
70  if (pthread_create(&m_th, NULL, PThread::create<WORKER>,
71  (void*)worker) != 0) {
72  m_th = 0;
73  }
74  }
75 #if (defined(__GLIBC__) && defined(__GNU_SOURCE) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 12)
76  if ((m_th != 0) && (thread_name != "")) {
77  try {
78  if (pthread_setname_np(m_th, thread_name.c_str()) != 0) {
79  LogFile::info("Failed to set process name %d", m_th);
80  }
81  char comp_name[64];
82  pthread_getname_np(m_th, comp_name, 16);
83  if (strcmp(thread_name.c_str(), comp_name) != 0) {
84  prctl(PR_SET_NAME, thread_name.c_str());
85  }
86  } catch (const std::exception& e) {
87  LogFile::error(e.what());
88  }
89  }
90 #endif
91  if (detached) {
92  detach();
93  m_th = 0;
94  }
95  }
96  ~PThread() {}
97 
98  public:
99  pthread_t id() { return m_th; }
100  pthread_t get_id() { return m_th; }
101  bool kill(int signo)
102  {
103  if (m_th == 0) return false;
104  return ::pthread_kill(m_th, signo) == 0;
105  }
106  bool is_alive() { return this->kill(0); }
107  bool detach()
108  {
109  if (m_th == 0) return false;
110  return ::pthread_detach(m_th) == 0;
111  }
112  bool join()
113  {
114  if (m_th == 0) return false;
115  return ::pthread_join(m_th, NULL) == 0;
116  }
117  bool cancel()
118  {
119  if (m_th == 0) return false;
120  return ::pthread_cancel(m_th) == 0;
121  }
122 
123  private:
124  pthread_t m_th;
125 
126  };
127 
129 }
130 
131 #endif
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::PThread
Definition: PThread.h:16