llthread.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llthread.h
  3.  * @brief Base classes for thread, mutex and condition handling.
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLTHREAD_H
  33. #define LL_LLTHREAD_H
  34. #include "llapp.h"
  35. #include "llapr.h"
  36. #include "apr_thread_cond.h"
  37. class LLThread;
  38. class LLMutex;
  39. class LLCondition;
  40. class LL_COMMON_API LLThread
  41. {
  42. public:
  43. typedef enum e_thread_status
  44. {
  45. STOPPED = 0, // The thread is not running.  Not started, or has exited its run function
  46. RUNNING = 1, // The thread is currently running
  47. QUITTING= 2  // Someone wants this thread to quit
  48. } EThreadStatus;
  49. LLThread(const std::string& name, apr_pool_t *poolp = NULL);
  50. virtual ~LLThread(); // Warning!  You almost NEVER want to destroy a thread unless it's in the STOPPED state.
  51. virtual void shutdown(); // stops the thread
  52. bool isQuitting() const { return (QUITTING == mStatus); }
  53. bool isStopped() const { return (STOPPED == mStatus); }
  54. static U32 currentID(); // Return ID of current thread
  55. static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
  56. public:
  57. // PAUSE / RESUME functionality. See source code for important usage notes.
  58. // Called from MAIN THREAD.
  59. void pause();
  60. void unpause();
  61. bool isPaused() { return isStopped() || mPaused == TRUE; }
  62. // Cause the thread to wake up and check its condition
  63. void wake();
  64. // Same as above, but to be used when the condition is already locked.
  65. void wakeLocked();
  66. // Called from run() (CHILD THREAD). Pause the thread if requested until unpaused.
  67. void checkPause();
  68. // this kicks off the apr thread
  69. void start(void);
  70. apr_pool_t *getAPRPool() { return mAPRPoolp; }
  71. LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
  72. private:
  73. BOOL mPaused;
  74. // static function passed to APR thread creation routine
  75. static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap);
  76. protected:
  77. std::string mName;
  78. LLCondition* mRunCondition;
  79. apr_thread_t *mAPRThreadp;
  80. apr_pool_t *mAPRPoolp;
  81. BOOL mIsLocalPool;
  82. EThreadStatus mStatus;
  83. //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
  84. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
  85. //      otherwise it will cause severe memory leaking!!! --bao
  86. LLVolatileAPRPool  *mLocalAPRFilePoolp ; 
  87. void setQuitting();
  88. // virtual function overridden by subclass -- this will be called when the thread runs
  89. virtual void run(void) = 0; 
  90. // virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
  91. virtual bool runCondition(void);
  92. // Lock/Unlock Run Condition -- use around modification of any variable used in runCondition()
  93. inline void lockData();
  94. inline void unlockData();
  95. // This is the predicate that decides whether the thread should sleep.  
  96. // It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access
  97. // data structures that are thread-unsafe.
  98. bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); }
  99. // To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
  100. // mRunCondition->lock();
  101. // if(!shouldSleep())
  102. //     mRunCondition->signal();
  103. // mRunCondition->unlock();
  104. };
  105. //============================================================================
  106. #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
  107. class LL_COMMON_API LLMutex
  108. {
  109. public:
  110. LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
  111. ~LLMutex();
  112. void lock(); // blocks
  113. void unlock();
  114. bool isLocked();  // non-blocking, but does do a lock/unlock so not free
  115. protected:
  116. apr_thread_mutex_t *mAPRMutexp;
  117. apr_pool_t *mAPRPoolp;
  118. BOOL mIsLocalPool;
  119. #if MUTEX_DEBUG
  120. std::map<U32, BOOL> mIsLocked;
  121. #endif
  122. };
  123. // Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
  124. class LL_COMMON_API LLCondition : public LLMutex
  125. {
  126. public:
  127. LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
  128. ~LLCondition();
  129. void wait(); // blocks
  130. void signal();
  131. void broadcast();
  132. protected:
  133. apr_thread_cond_t *mAPRCondp;
  134. };
  135. class LLMutexLock
  136. {
  137. public:
  138. LLMutexLock(LLMutex* mutex)
  139. {
  140. mMutex = mutex;
  141. mMutex->lock();
  142. }
  143. ~LLMutexLock()
  144. {
  145. mMutex->unlock();
  146. }
  147. private:
  148. LLMutex* mMutex;
  149. };
  150. //============================================================================
  151. void LLThread::lockData()
  152. {
  153. mRunCondition->lock();
  154. }
  155. void LLThread::unlockData()
  156. {
  157. mRunCondition->unlock();
  158. }
  159. //============================================================================
  160. // see llmemory.h for LLPointer<> definition
  161. class LL_COMMON_API LLThreadSafeRefCount
  162. {
  163. public:
  164. static void initThreadSafeRefCount(); // creates sMutex
  165. static void cleanupThreadSafeRefCount(); // destroys sMutex
  166. private:
  167. static LLMutex* sMutex;
  168. private:
  169. LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented
  170. LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented
  171. protected:
  172. virtual ~LLThreadSafeRefCount(); // use unref()
  173. public:
  174. LLThreadSafeRefCount();
  175. void ref()
  176. {
  177. if (sMutex) sMutex->lock();
  178. mRef++; 
  179. if (sMutex) sMutex->unlock();
  180. S32 unref()
  181. {
  182. llassert(mRef >= 1);
  183. if (sMutex) sMutex->lock();
  184. S32 res = --mRef;
  185. if (sMutex) sMutex->unlock();
  186. if (0 == res) 
  187. {
  188. delete this; 
  189. return 0;
  190. }
  191. return res;
  192. }
  193. S32 getNumRefs() const
  194. {
  195. return mRef;
  196. }
  197. private: 
  198. S32 mRef; 
  199. };
  200. //============================================================================
  201. // Simple responder for self destructing callbacks
  202. // Pure virtual class
  203. class LL_COMMON_API LLResponder : public LLThreadSafeRefCount
  204. {
  205. protected:
  206. virtual ~LLResponder();
  207. public:
  208. virtual void completed(bool success) = 0;
  209. };
  210. //============================================================================
  211. #endif // LL_LLTHREAD_H