diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llthread.h | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llcommon/llthread.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h new file mode 100644 index 0000000..2a13d72 --- /dev/null +++ b/linden/indra/llcommon/llthread.h | |||
@@ -0,0 +1,183 @@ | |||
1 | /** | ||
2 | * @file llthread.h | ||
3 | * @brief Base classes for thread, mutex and condition handling. | ||
4 | * | ||
5 | * Copyright (c) 2004-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLTHREAD_H | ||
29 | #define LL_LLTHREAD_H | ||
30 | |||
31 | #include "llapr.h" | ||
32 | #include "llapp.h" | ||
33 | |||
34 | #include "apr-1/apr_thread_cond.h" | ||
35 | |||
36 | class LLThread; | ||
37 | class LLMutex; | ||
38 | class LLCondition; | ||
39 | |||
40 | class 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 | |||
50 | LLThread(const std::string& name, apr_pool_t *poolp = NULL); | ||
51 | virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. | ||
52 | |||
53 | static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure. | ||
54 | |||
55 | |||
56 | bool isQuitting() const; | ||
57 | bool isStopped() const; | ||
58 | |||
59 | // PAUSE / RESUME functionality. See source code for important usage notes. | ||
60 | public: | ||
61 | // Called from MAIN THREAD. | ||
62 | void pause(); | ||
63 | void unpause(); | ||
64 | bool isPaused() { return mPaused ? true : false; } | ||
65 | |||
66 | // Cause the thread to wake up and check its condition | ||
67 | void wake(); | ||
68 | |||
69 | // Same as above, but to be used when the condition is already locked. | ||
70 | void wakeLocked(); | ||
71 | |||
72 | // Called from run() (CHILD THREAD). Pause the thread if requested until unpaused. | ||
73 | void checkPause(); | ||
74 | |||
75 | // this kicks off the apr thread | ||
76 | void start(void); | ||
77 | |||
78 | apr_pool_t *getAPRPool() { return mAPRPoolp; } | ||
79 | |||
80 | private: | ||
81 | BOOL mPaused; | ||
82 | |||
83 | // static function passed to APR thread creation routine | ||
84 | static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap); | ||
85 | |||
86 | protected: | ||
87 | std::string mName; | ||
88 | LLCondition* mRunCondition; | ||
89 | |||
90 | apr_thread_t *mAPRThreadp; | ||
91 | apr_pool_t *mAPRPoolp; | ||
92 | BOOL mIsLocalPool; | ||
93 | EThreadStatus mStatus; | ||
94 | |||
95 | void setQuitting(); | ||
96 | |||
97 | // virtual function overridden by subclass -- this will be called when the thread runs | ||
98 | virtual void run(void) = 0; | ||
99 | |||
100 | // virtual predicate function -- returns true if the thread should wake up, false if it should sleep. | ||
101 | virtual bool runCondition(void); | ||
102 | |||
103 | // Lock/Unlock Run Condition -- use around modification of any variable used in runCondition() | ||
104 | inline void lockData(); | ||
105 | inline void unlockData(); | ||
106 | |||
107 | // This is the predicate that decides whether the thread should sleep. | ||
108 | // It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access | ||
109 | // data structures that are thread-unsafe. | ||
110 | bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); } | ||
111 | |||
112 | // To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following: | ||
113 | // mRunCondition->lock(); | ||
114 | // if(!shouldSleep()) | ||
115 | // mRunCondition->signal(); | ||
116 | // mRunCondition->unlock(); | ||
117 | }; | ||
118 | |||
119 | //============================================================================ | ||
120 | |||
121 | class LLMutex | ||
122 | { | ||
123 | public: | ||
124 | LLMutex(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. | ||
125 | ~LLMutex(); | ||
126 | |||
127 | void lock(); // blocks | ||
128 | void unlock(); | ||
129 | bool isLocked(); // non-blocking, but does do a lock/unlock so not free | ||
130 | |||
131 | protected: | ||
132 | apr_thread_mutex_t *mAPRMutexp; | ||
133 | apr_pool_t *mAPRPoolp; | ||
134 | BOOL mIsLocalPool; | ||
135 | }; | ||
136 | |||
137 | // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). | ||
138 | class LLCondition : public LLMutex | ||
139 | { | ||
140 | public: | ||
141 | LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. | ||
142 | ~LLCondition(); | ||
143 | |||
144 | void wait(); // blocks | ||
145 | void signal(); | ||
146 | void broadcast(); | ||
147 | |||
148 | protected: | ||
149 | apr_thread_cond_t *mAPRCondp; | ||
150 | }; | ||
151 | |||
152 | class LLMutexLock | ||
153 | { | ||
154 | public: | ||
155 | LLMutexLock(LLMutex* mutex) | ||
156 | { | ||
157 | mMutex = mutex; | ||
158 | mMutex->lock(); | ||
159 | } | ||
160 | ~LLMutexLock() | ||
161 | { | ||
162 | mMutex->unlock(); | ||
163 | } | ||
164 | private: | ||
165 | LLMutex* mMutex; | ||
166 | }; | ||
167 | |||
168 | //============================================================================ | ||
169 | |||
170 | void LLThread::lockData() | ||
171 | { | ||
172 | mRunCondition->lock(); | ||
173 | } | ||
174 | |||
175 | void LLThread::unlockData() | ||
176 | { | ||
177 | mRunCondition->unlock(); | ||
178 | } | ||
179 | |||
180 | |||
181 | //============================================================================ | ||
182 | |||
183 | #endif // LL_LLTHREAD_H | ||