Thread_POSIX.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // Thread_POSIX.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/Thread_POSIX.h#3 $
  5. //
  6. // Library: Foundation
  7. // Package: Threading
  8. // Module: Thread
  9. //
  10. // Definition of the ThreadImpl class for POSIX Threads.
  11. //
  12. // Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_Thread_POSIX_INCLUDED
  18. #define Foundation_Thread_POSIX_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/Runnable.h"
  21. #include "Poco/SignalHandler.h"
  22. #include "Poco/Event.h"
  23. #include "Poco/RefCountedObject.h"
  24. #include "Poco/AutoPtr.h"
  25. #include "Poco/SharedPtr.h"
  26. #include <pthread.h>
  27. // must be limits.h (not <climits>) for PTHREAD_STACK_MIN on Solaris
  28. #include <limits.h>
  29. #if !defined(POCO_NO_SYS_SELECT_H)
  30. #include <sys/select.h>
  31. #endif
  32. #include <errno.h>
  33. #if defined(POCO_VXWORKS)
  34. #include <cstring>
  35. #endif
  36. namespace Poco {
  37. class Foundation_API ThreadImpl
  38. {
  39. public:
  40. typedef pthread_t TIDImpl;
  41. typedef void (*Callable)(void*);
  42. enum Priority
  43. {
  44. PRIO_LOWEST_IMPL,
  45. PRIO_LOW_IMPL,
  46. PRIO_NORMAL_IMPL,
  47. PRIO_HIGH_IMPL,
  48. PRIO_HIGHEST_IMPL
  49. };
  50. enum Policy
  51. {
  52. POLICY_DEFAULT_IMPL = SCHED_OTHER
  53. };
  54. ThreadImpl();
  55. ~ThreadImpl();
  56. TIDImpl tidImpl() const;
  57. void setPriorityImpl(int prio);
  58. int getPriorityImpl() const;
  59. void setOSPriorityImpl(int prio, int policy = SCHED_OTHER);
  60. int getOSPriorityImpl() const;
  61. static int getMinOSPriorityImpl(int policy);
  62. static int getMaxOSPriorityImpl(int policy);
  63. void setStackSizeImpl(int size);
  64. int getStackSizeImpl() const;
  65. void startImpl(SharedPtr<Runnable> pTarget);
  66. void joinImpl();
  67. bool joinImpl(long milliseconds);
  68. bool isRunningImpl() const;
  69. static void sleepImpl(long milliseconds);
  70. static void yieldImpl();
  71. static ThreadImpl* currentImpl();
  72. static TIDImpl currentTidImpl();
  73. protected:
  74. static void* runnableEntry(void* pThread);
  75. static int mapPrio(int prio, int policy = SCHED_OTHER);
  76. static int reverseMapPrio(int osPrio, int policy = SCHED_OTHER);
  77. private:
  78. class CurrentThreadHolder
  79. {
  80. public:
  81. CurrentThreadHolder()
  82. {
  83. if (pthread_key_create(&_key, NULL))
  84. throw SystemException("cannot allocate thread context key");
  85. }
  86. ~CurrentThreadHolder()
  87. {
  88. pthread_key_delete(_key);
  89. }
  90. ThreadImpl* get() const
  91. {
  92. return reinterpret_cast<ThreadImpl*>(pthread_getspecific(_key));
  93. }
  94. void set(ThreadImpl* pThread)
  95. {
  96. pthread_setspecific(_key, pThread);
  97. }
  98. private:
  99. pthread_key_t _key;
  100. };
  101. struct ThreadData: public RefCountedObject
  102. {
  103. ThreadData():
  104. thread(0),
  105. prio(PRIO_NORMAL_IMPL),
  106. policy(SCHED_OTHER),
  107. done(false),
  108. stackSize(POCO_THREAD_STACK_SIZE),
  109. started(false),
  110. joined(false)
  111. {
  112. #if defined(POCO_VXWORKS)
  113. // This workaround is for VxWorks 5.x where
  114. // pthread_init() won't properly initialize the thread.
  115. std::memset(&thread, 0, sizeof(thread));
  116. #endif
  117. }
  118. SharedPtr<Runnable> pRunnableTarget;
  119. pthread_t thread;
  120. int prio;
  121. int osPrio;
  122. int policy;
  123. Event done;
  124. std::size_t stackSize;
  125. bool started;
  126. bool joined;
  127. };
  128. AutoPtr<ThreadData> _pData;
  129. static CurrentThreadHolder _currentThreadHolder;
  130. #if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS)
  131. SignalHandler::JumpBufferVec _jumpBufferVec;
  132. friend class SignalHandler;
  133. #endif
  134. };
  135. //
  136. // inlines
  137. //
  138. inline int ThreadImpl::getPriorityImpl() const
  139. {
  140. return _pData->prio;
  141. }
  142. inline int ThreadImpl::getOSPriorityImpl() const
  143. {
  144. return _pData->osPrio;
  145. }
  146. inline bool ThreadImpl::isRunningImpl() const
  147. {
  148. return !_pData->pRunnableTarget.isNull();
  149. }
  150. inline void ThreadImpl::yieldImpl()
  151. {
  152. sched_yield();
  153. }
  154. inline int ThreadImpl::getStackSizeImpl() const
  155. {
  156. return static_cast<int>(_pData->stackSize);
  157. }
  158. inline ThreadImpl::TIDImpl ThreadImpl::tidImpl() const
  159. {
  160. return _pData->thread;
  161. }
  162. } // namespace Poco
  163. #endif // Foundation_Thread_POSIX_INCLUDED