summaryrefslogtreecommitdiff
path: root/src/TNetLib/Thread.h
blob: ba6d7ba1992336a0cd01529d95ad198dbb040b88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef _TNET_THREAD_H
#define _TNET_THREAD_H

namespace TNet {

class Thread {
 public:
  Thread() 
  { }
  virtual ~Thread() 
  { }

  int Start(void* arg);

 protected:
  static void* EntryPoint(void*);
  virtual void Execute(void*) = 0; ///< Override this function
  void* Arg() const { return arg_; }
  void Arg(void* a) { arg_ = a; }

 private:
  pthread_t thread_id_;
  void * arg_;
};

int Thread::Start(void * arg) {
  Arg(arg); // store user data
 
  int ret=0;
  //create thread as detached (don't wait for it)
  pthread_attr_t tattr;
  ret |= pthread_attr_init(&tattr);
  ret |= pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED);
  ret |= pthread_create(&thread_id_, &tattr, &Thread::EntryPoint, this);
  if(ret != 0) KALDI_ERR << "Failed to create thread";
  return ret;
}

/*static */
void* Thread::EntryPoint(void* pthis) try {
  Thread* pt = (Thread*)pthis;
  pt->Execute(pt->Arg());
  return NULL;
} catch (std::exception& rExc) {
  std::cerr << "Exception thrown" << std::endl;
  std::cerr << rExc.what() << std::endl;
  exit(1);
}


} //namespace TNet

#endif