Go to the documentation of this file.00001
00002 #ifndef acsThreadBase_h
00003 #define acsThreadBase_h
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 #include <acsutil.h>
00036 #include <acsutilThreadInit.h>
00037
00038 #include <map>
00039 #include <vector>
00040
00041 #include <ace/Thread.h>
00042 #include <ace/Thread_Manager.h>
00043 #include <ace/Synch.h>
00044
00045 #include <acscommonC.h>
00046 #include <ace/SString.h>
00047 #include <logging.h>
00048 #include <loggingLoggable.h>
00049
00050 #include "acsthreadErrType.h"
00051
00052 namespace ACS {
00053
00058 TimeInterval getTime();
00059
00105 class ThreadBase : public Logging::Loggable
00106 {
00107 public:
00108
00118 static TimeInterval defaultResponseTime;
00119
00128 static TimeInterval defaultSleepTime;
00129
00131 static ThreadBase * NullThreadBase;
00132
00134 static InitThreadFunc InitThread;
00135
00137 static DoneThreadFunc DoneThread;
00138
00139 public:
00140
00151 enum SleepReturn {
00152 SLEEP_OK=0,
00153 SLEEP_SUSPEND,
00154 SLEEP_INTERRUPTED,
00155 SLEEP_ERROR
00156 };
00157
00179 ThreadBase(const ACE_CString& _name, ACE_Thread_Manager* _threadManager,
00180 void* _threadProcedure, void* _parameter,
00181 const TimeInterval& _responseTime=ThreadBase::defaultResponseTime,
00182 const TimeInterval& _sleepTime=ThreadBase::defaultSleepTime,
00183 const bool _create=true,
00184 const long _thrFlags= THR_NEW_LWP | THR_DETACHED,
00185 const size_t _stackSize=ACE_DEFAULT_THREAD_STACKSIZE);
00186
00199 virtual ~ThreadBase();
00200
00212 static void setInitializers(InitThreadFunc InitThread_, DoneThreadFunc DoneThread_) {
00213 InitThread=InitThread_;
00214 DoneThread=DoneThread_;
00215 }
00216
00221 ACE_CString getName() const { return name_m; }
00222
00228 void* getThreadProcedure() const { return threadProcedure_mp; }
00229
00235 TimeInterval getResponseTime() const { return responseTime_m; }
00236
00242 void setResponseTime(const TimeInterval& _responseTime) { responseTime_m=_responseTime; };
00243
00249 TimeInterval getSleepTime() const { return sleepTime_m; }
00250
00256 void setSleepTime(const TimeInterval& _sleepTime) {
00257 sleepTime_m=_sleepTime;
00258 };
00259
00264 void setPriority(int _priority);
00265
00270 int getPriority();
00271
00279 bool suspend();
00280
00285 virtual bool resume();
00286
00291 bool isSuspended() const { return suspendStatus_m != 0; }
00292
00297 bool isStopped() const { return stopped_m; }
00298
00304 virtual void exit() { exitRequest_m=true; }
00305
00310 bool exitRequested() const { return exitRequest_m; }
00311
00317 void setStopped() { stopped_m=true; }
00318
00319
00330 bool stop( bool terminating = false );
00331
00332
00345 bool cancel();
00346
00355 bool terminate();
00356
00364 bool restart();
00365
00373 void makeTimeInterval();
00374
00383 bool isResponding() const;
00384
00389 bool isAlive() const { return !stopped_m; }
00390
00402 bool check();
00403
00428 SleepReturn sleep(TimeInterval timeIn100ns = 0) const;
00429
00430
00434 ACE_thread_t getThreadID() { return threadID_m; }
00435
00436 protected:
00451 bool create(const long _thrFlags= THR_NEW_LWP | THR_DETACHED);
00452
00458 virtual void yield();
00459
00460 private:
00461
00463 void* threadProcedure_mp;
00464
00466 const void* parameter_mp;
00467
00469 TimeInterval responseTime_m;
00470
00472 TimeInterval sleepTime_m;
00473
00475 TimeInterval timeStamp_m;
00476
00478 volatile int suspendStatus_m;
00479
00481 volatile bool exitRequest_m;
00482
00484 volatile bool stopped_m;
00485
00487 ACE_CString name_m;
00488
00489
00491 ACE_thread_t threadID_m;
00492
00494 long thrFlags_m;
00495
00497 size_t stackSize_m;
00498
00500 ACE_Thread_Manager * threadManager_mp;
00501
00503 mutable ACE_Thread_Semaphore m_suspendSemaphore;
00504 mutable ACE_Semaphore m_sleepSemaphore;
00505 };
00506
00507
00508
00510 typedef std::map<ACE_CString, ThreadBase*> ThreadMap;
00511
00512
00519
00520
00521
00527 class ThreadManagerBase
00528 {
00535
00536
00537 public:
00538
00542 ThreadManagerBase()
00543 {
00544 threadManager_mp = ACE_Thread_Manager::instance();
00545 }
00546
00551 ~ThreadManagerBase();
00552
00557 int getThreadCount() const {return threads_m.size();}
00558
00564 ACE_CString getThreadName(const int pos) const { return threads_m[pos]->getName(); }
00565
00566
00572 ThreadBase* getThreadAt(const int pos) const { return static_cast<ThreadBase*>(threads_m[pos]); }
00573
00574
00580 ThreadBase* getThreadByName(const ACE_CString& name) {
00581 ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_addRemoveMutex);
00582
00583 ThreadMap::iterator i = threadMap_m.find(name);
00584 if (i!=threadMap_m.end())
00585 return static_cast<ThreadBase*>((*i).second);
00586 else
00587 return NULL;
00588 }
00589
00595 ThreadBase* getThreadByID(ACE_thread_t id)
00596 {
00597
00598 for(unsigned int i=0UL; i < threads_m.size(); i++)
00599 if (threads_m[i]->getThreadID() == id)
00600 return threads_m[i];
00601 return NULL;
00602 }
00603
00604
00621 ThreadBase * create(const ACE_CString& name, void * threadProc, void * parameter,
00622 const TimeInterval& responseTime=ThreadBase::defaultResponseTime,
00623 const TimeInterval& sleepTime=ThreadBase::defaultSleepTime,
00624 const long _thrFlags= THR_NEW_LWP | THR_DETACHED,
00625 const size_t _stackSize=ACE_DEFAULT_THREAD_STACKSIZE);
00626
00635 bool add(const ACE_CString& name, ThreadBase * acsBaseThread);
00636
00643 bool stop(const ACE_CString& name);
00644
00650 bool stopAll();
00651
00657 void exit(const ACE_CString& name);
00658
00663 void exitAll();
00664
00672 bool cancel(const ACE_CString& name);
00673
00678 bool cancelAll();
00679
00685 bool terminate(const ACE_CString& name);
00686
00691 bool terminateAll();
00692
00699 bool restart(const ACE_CString& name);
00700
00705 bool restartAll();
00706
00712 bool restartDead();
00713
00719 bool suspend(const ACE_CString& name);
00720
00725 bool suspendAll();
00726
00732 bool resume(const ACE_CString& name);
00733
00738 bool resumeAll();
00739
00746 bool isAlive(const ACE_CString& name);
00747
00754 bool areAllAlive();
00755
00761 int join(const ACE_thread_t& tid);
00762
00768 int join(const ThreadBase *th);
00769
00774 ACE_Thread_Manager* getACEThreadManager() { return threadManager_mp; }
00775
00776 protected:
00777
00783 void add2map(const ACE_CString& name, ThreadBase* thread)
00784 {
00785
00786 threadMap_m[name]=thread;
00787 threads_m.push_back(thread);
00788 }
00789
00790 void removeFromMap(const ACE_CString& name)
00791 {
00792 ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_addRemoveMutex);
00793
00794 ThreadMap::iterator i = threadMap_m.find(name);
00795 if (i!=threadMap_m.end())
00796 {
00797 for (std::vector<ThreadBase*>::iterator thr = threads_m.begin(); thr!=threads_m.end(); ++thr)
00798 {
00799 if (static_cast<ThreadBase*>((*i).second) == *thr)
00800 {
00801 threads_m.erase(thr);
00802 break;
00803 }
00804 }
00805 }
00806 threadMap_m.erase(name);
00807 }
00808
00809 protected:
00811 ACE_Recursive_Thread_Mutex m_addRemoveMutex;
00812
00813 private:
00814
00816 ACE_Thread_Manager * threadManager_mp;
00817
00819 ThreadMap threadMap_m;
00820
00822 std::vector<ThreadBase*> threads_m;
00823
00827 void operator=(const ThreadManagerBase&);
00828
00832 ThreadManagerBase(const ThreadManagerBase&);
00833
00834 };
00835
00843 class ThreadBaseParameter {
00844
00845 public:
00846
00852 ThreadBaseParameter(ThreadBase * thread,
00853 const void * parameter = 0) :
00854 thread_mp(thread), parameter_mp(parameter) {}
00855
00860 const void * getParameter() const { return parameter_mp; }
00861
00866 ThreadBase * getThreadBase() const { return thread_mp; }
00867
00872
00873 private:
00874
00876 ThreadBase * thread_mp;
00877
00879 const void * parameter_mp;
00880 };
00881
00882
00917 class ThreadSyncGuard
00918 {
00919 public:
00920
00927 ThreadSyncGuard(ACE_Recursive_Thread_Mutex * mutex, bool block=true);
00928
00933 ~ThreadSyncGuard();
00934
00938 void acquire();
00939
00943 void release();
00944
00946 ACE_Recursive_Thread_Mutex * mutex_mp;
00947
00949 bool acquired_m;
00950 };
00951
00952 };
00953
00954 #endif
00955
00956
00957
00958
00959