sttcl  v0.9c
STTCL C++ template state machine framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ClassMethodThread.h
Go to the documentation of this file.
1 
25 #ifndef CLASSMETHODTHREAD_H_
26 #define CLASSMETHODTHREAD_H_
27 
28 #include "SttclThread.h"
29 #include "SttclMutex.h"
30 
31 namespace sttcl
32 {
40 template
41 < class T
42 , class UserArgs = void
43 , class ThreadImpl = STTCL_DEFAULT_THREADIMPL
44 , class MutexImpl = STTCL_DEFAULT_MUTEXIMPL
45 >
47 : public sttcl::internal::SttclThread<ThreadImpl>
48 {
49 public:
53  typedef void* (T::*ThreadMethodPtr)(UserArgs*);
54 
55 private:
56  struct RunArgs
57  {
59  T* instance;
60  ThreadMethodPtr threadMethod;
61  UserArgs* userArgs;
62 
63  RunArgs(ClassMethodThread<T,UserArgs,ThreadImpl,MutexImpl>* argThreadInstance,T* argInstance, ThreadMethodPtr argThreadMethod, UserArgs* argUserArgs = 0)
64  : threadInstance(argThreadInstance)
65  , instance(argInstance)
66  , threadMethod(argThreadMethod)
67  , userArgs(argUserArgs)
68  {
69  }
70  RunArgs(const RunArgs& rhs)
71  : threadInstance(rhs.threadInstance)
72  , instance(rhs.instance)
73  , threadMethod(rhs.threadMethod)
74  , userArgs(rhs.userArgs)
75  {
76  }
77  RunArgs& operator=(const RunArgs& rhs)
78  {
79  threadInstance = rhs.threadInstance;
80  instance = rhs.instance;
81  threadMethod = rhs.threadMethod;
82  userArgs = rhs.userArgs;
83  return *this;
84  }
85 
86  private:
87  RunArgs();
88  };
89 public:
95  ClassMethodThread(T* argInstance, ThreadMethodPtr argThreadMethod)
96  : sttcl::internal::SttclThread<ThreadImpl>(internalThreadMethod)
97  , runArgs(this,argInstance,argThreadMethod)
98  , running(false)
99  , threadMutex()
100  {
101  }
102 
107  {
108  }
109 
114  bool run(UserArgs* userArgs = 0)
115  {
116  if(!isRunning())
117  {
118  runArgs.userArgs = userArgs;
120  }
121  return false;
122  }
123 
124  bool isRunning()
125  {
126  sttcl::internal::AutoLocker<MutexImpl> lock(threadMutex);
127  return running;
128  }
129 
130  void join()
131  {
132  if(!isSelf(*this))
133  {
135  }
136  }
137 
138 private:
139  static void* internalThreadMethod(void* args)
140  {
141  void * result = 0;
142  RunArgs* runArgs = reinterpret_cast<RunArgs*>(args);
143  ClassMethodThread<T,UserArgs,ThreadImpl,MutexImpl>* thisPtr = runArgs->threadInstance;
144 
145 // if(!isSelf(*thisPtr) && !thisPtr->isRunning())
146 // {
147  { sttcl::internal::AutoLocker<MutexImpl> lock(thisPtr->threadMutex);
148  thisPtr->running = true;
149  }
150  T* instance = runArgs->instance;
151  ThreadMethodPtr threadMethod = runArgs->threadMethod;
152  result = (instance->*threadMethod)(runArgs->userArgs);
153  { sttcl::internal::AutoLocker<MutexImpl> lock(thisPtr->threadMutex);
154  thisPtr->running = false;
155  }
156 // }
157  return result;
158  }
159 
161  ClassMethodThread(const ClassMethodThread<T,UserArgs,ThreadImpl>& rhs);
162  ClassMethodThread<T,UserArgs,ThreadImpl>& operator=(const ClassMethodThread<T,UserArgs,ThreadImpl>& rhs);
163 
164  RunArgs runArgs;
165  bool running;
166  MutexImpl threadMutex;
167 };
168 
169 }
170 #endif /* CLASSMETHODTHREAD_H_ */