Revised OpenFlow Library  v0.6.0dev
 All Classes Files Functions Variables Friends Groups Pages
cthread.h
1 /*
2  * cthread.h
3  *
4  * Created on: 26.10.2014
5  * Author: andreas
6  */
7 
8 #ifndef CTHREAD_H_
9 #define CTHREAD_H_
10 
11 #include <pthread.h>
12 
13 #include <bitset>
14 
15 #include <rofl/common/ciosrv.h>
16 #include <rofl/common/croflexception.h>
17 #include <rofl/common/logging.h>
18 
19 namespace rofl {
20 namespace common {
21 
22 class eRofThreadBase : public RoflException {
23 public:
24  eRofThreadBase(const std::string& __arg) : RoflException(__arg) {};
25 };
27 public:
28  eRofThreadFailed(const std::string& __arg) : eRofThreadBase(__arg) {};
29 };
30 
31 class cthread {
32 
33  enum cthread_flag_t {
34  FLAGS_THREAD_IS_RUNNING = 1,
35  };
36 
37 public:
38 
42  cthread() : tid(0), result(0) {};
43 
47  virtual
48  ~cthread() {};
49 
50 protected:
51 
55  bool
56  is_running() const
57  { return flags.test(FLAGS_THREAD_IS_RUNNING); };
58 
62  void
63  set_thread_id(pthread_t tid) { this->tid = tid; };
64 
68  pthread_t
69  get_thread_id() const { return tid; };
70 
74  void
75  set_result(int result) { this->result = result; };
76 
80  const int&
81  get_result() const { return result; };
82 
83 protected:
84 
88  virtual void
89  init_thread() {}; // to be overwritten by derived class
90 
94  virtual void
95  release_thread() {}; // to be overwritten by derived class
96 
100  void
101  start(const pthread_attr_t* attr = (const pthread_attr_t*)0) {
102  rofl::logging::debug2 << "[rofl-common][cthread][start_thread] create" << std::endl;
103  int rc = pthread_create(&tid, attr, cthread::run_thread, (void*)this);
104  rofl::logging::debug2 << "[rofl-common][cthread][start_thread] create done tid: 0x" << tid << std::endl;
105 
106  if (rc != 0) {
107  switch (rc) {
108  case EAGAIN: {
109  throw eRofThreadFailed("cthread::start_thread() insufficient resources");
110  } break;
111  case EINVAL: {
112  throw eRofThreadFailed("cthread::start_thread() invalid thread attributes");
113  } break;
114  case EPERM: {
115  throw eRofThreadFailed("cthread::start_thread() permission denied");
116  } break;
117  default: {
118  throw eRofThreadFailed("cthread::start_thread() unknown error occured");
119  };
120  }
121  } else {
122  flags.set(FLAGS_THREAD_IS_RUNNING);
123  }
124  };
125 
129  void
130  stop() {
131  rofl::logging::debug2 << "[rofl-common][cthread][stop_thread] stop cioloop tid: 0x" << tid << std::endl;
132  rofl::cioloop::get_loop(get_thread_id()).stop();
133  rofl::logging::debug2 << "[rofl-common][cthread][stop_thread] join tid: 0x" << tid << std::endl;
134  pthread_cancel(tid);
135  void* retval;
136  int rc = pthread_join(tid, &retval);
137  rofl::logging::debug2 << "[rofl-common][cthread][stop_thread] join done tid: 0x" << tid << std::endl;
138 
139  if (rc != 0) {
140  switch (rc) {
141  case EDEADLK: {
142  throw eRofThreadFailed("cthread::stop_thread() -join- deadlock");
143  } break;
144  case EINVAL: {
145  throw eRofThreadFailed("cthread::stop_thread() -join- thread not joinable");
146  } break;
147  case ESRCH: {
148  //throw eRofThreadFailed("cthread::stop_thread() -join- thread not found");
149  } break;
150  default: {
151  throw eRofThreadFailed("cthread::stop_thread() -join- unknown error");
152  };
153  }
154  }
155 
156  release_thread();
157 
159 
160  flags.reset(FLAGS_THREAD_IS_RUNNING);
161  };
162 
163 private:
164 
168  static void*
169  run_thread(void* arg) {
170  cthread& thread = *(static_cast<cthread*>( arg ));
171  thread.set_thread_id(pthread_self());
172 
173  thread.init_thread();
174 
175  rofl::cioloop::get_loop(thread.get_thread_id()).run();
176 
177  return (void*)&(thread.get_result());
178  };
179 
180 protected:
181 
182  std::bitset<32> flags;
183  pthread_t tid;
184  int result;
185 };
186 
187 }; // end of namespace common
188 }; // end of namespace rofl
189 
190 #endif /* CTHREAD_H_ */
void stop()
Terminates cioloop instance running in thread identified by this->tid.
Definition: ciosrv.h:93
Definition: cthread.h:26
static cioloop & get_loop(pthread_t tid=0)
Returns reference to cioloop instance identified by thread id or if none is specified, cioloop of local thread.
Definition: ciosrv.h:57
Definition: cthread.h:31
static void drop_loop(pthread_t tid)
Drop.
Definition: ciosrv.h:71
Definition: cthread.h:22
Definition: croflexception.h:27