Thread_POSIX.h 3.8 KB

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