aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llqueuedthread.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llqueuedthread.h221
1 files changed, 221 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llqueuedthread.h b/linden/indra/llcommon/llqueuedthread.h
new file mode 100644
index 0000000..cc21b3b
--- /dev/null
+++ b/linden/indra/llcommon/llqueuedthread.h
@@ -0,0 +1,221 @@
1/**
2 * @file llqueuedthread.h
3 * @brief
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_LLQUEUEDTHREAD_H
29#define LL_LLQUEUEDTHREAD_H
30
31#include <queue>
32#include <string>
33#include <map>
34#include <set>
35
36#include "llapr.h"
37
38#include "llthread.h"
39#include "llsimplehash.h"
40
41//============================================================================
42// Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small
43// It is assumed that LLQueuedThreads are rarely created/destroyed.
44
45class LLQueuedThread : public LLThread
46{
47 //------------------------------------------------------------------------
48public:
49 enum priority_t {
50 PRIORITY_IMMEDIATE = 0x7FFFFFFF,
51 PRIORITY_URGENT = 0x40000000,
52 PRIORITY_HIGH = 0x30000000,
53 PRIORITY_NORMAL = 0x20000000,
54 PRIORITY_LOW = 0x10000000,
55 PRIORITY_LOWBITS = 0x0FFFFFFF
56 };
57 enum status_t {
58 STATUS_EXPIRED = -1,
59 STATUS_UNKNOWN = 0,
60 STATUS_QUEUED = 1,
61 STATUS_INPROGRESS = 2,
62 STATUS_COMPLETE = 3,
63 STATUS_ABORT = 4,
64 STATUS_ABORTED = 5,
65 STATUS_DELETE = 6
66 };
67 enum flags_t {
68 AUTO_COMPLETE = 1,
69 AUTO_DELETE = 2 // child-class dependent
70 };
71
72 typedef U32 handle_t;
73
74 //------------------------------------------------------------------------
75public:
76
77 class QueuedRequest : public LLSimpleHashEntry<handle_t>
78 {
79 friend class LLQueuedThread;
80
81 protected:
82 ~QueuedRequest(); // use deleteRequest()
83
84 public:
85 QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
86
87 status_t getStatus()
88 {
89 return mStatus;
90 }
91 U32 getPriority() const
92 {
93 return mPriority;
94 }
95 U32 getFlags() const
96 {
97 return mFlags;
98 }
99 bool higherPriority(const QueuedRequest& second) const
100 {
101 if ( mPriority == second.mPriority)
102 return mHashKey < second.mHashKey;
103 else
104 return mPriority > second.mPriority;
105 }
106
107 protected:
108 status_t setStatus(status_t newstatus)
109 {
110 status_t oldstatus = mStatus;
111 mStatus = newstatus;
112 return oldstatus;
113 }
114 status_t abortRequest(U32 flags)
115 {
116 // NOTE: flags are |'d
117 if (mStatus == STATUS_QUEUED)
118 {
119 setStatus(STATUS_ABORT);
120 }
121 mFlags |= flags;
122 status_t status = mStatus;
123 return status;
124 }
125 status_t setFlags(U32 flags)
126 {
127 // NOTE: flags are |'d
128 mFlags |= flags;
129 status_t status = mStatus;
130 return status;
131 }
132
133 virtual void finishRequest(); // Always called when after has been processed
134 virtual void deleteRequest(); // Only method to delete a request
135
136 void setPriority(U32 pri)
137 {
138 // Only do this on a request that is not in a queued list!
139 mPriority = pri;
140 };
141
142 protected:
143 LLAtomic32<status_t> mStatus;
144 U32 mPriority;
145 U32 mFlags;
146 };
147
148protected:
149 struct queued_request_less
150 {
151 bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
152 {
153 return lhs->higherPriority(*rhs); // higher priority in front of queue (set)
154 }
155 };
156
157 //------------------------------------------------------------------------
158
159public:
160 static handle_t nullHandle() { return handle_t(0); }
161
162public:
163 LLQueuedThread(const std::string& name, bool threaded = TRUE, bool runalways = TRUE);
164 virtual ~LLQueuedThread();
165
166private:
167 // No copy constructor or copy assignment
168 LLQueuedThread(const LLQueuedThread&);
169 LLQueuedThread& operator=(const LLQueuedThread&);
170
171 virtual bool runCondition(void);
172 virtual void run(void);
173
174protected:
175 handle_t generateHandle();
176 bool addRequest(QueuedRequest* req);
177 int processNextRequest(void);
178
179 virtual bool processRequest(QueuedRequest* req) = 0;
180
181public:
182 bool waitForResult(handle_t handle, bool auto_complete = true);
183
184 void update(U32 ms_elapsed);
185 void updateQueue(S32 inc);
186 void waitOnPending();
187 void printQueueStats();
188
189 S32 getPending(bool child_thread = false);
190 bool getThreaded() { return mThreaded ? true : false; }
191 bool getRunAlways() { return mRunAlways ? true : false; }
192
193 // Request accessors
194 status_t getRequestStatus(handle_t handle);
195 status_t abortRequest(handle_t handle, U32 flags = 0);
196 status_t setFlags(handle_t handle, U32 flags);
197 void setPriority(handle_t handle, U32 priority);
198 bool completeRequest(handle_t handle);
199 // This is public for support classes like LLWorkerThread,
200 // but generally the methods above should be used.
201 QueuedRequest* getRequest(handle_t handle);
202
203 // debug (see source)
204 bool check();
205
206protected:
207 BOOL mThreaded; // if false, run on main thread and do updates during update()
208 BOOL mRunAlways; // if false, only wake the threads when updateClass() is called
209 LLAtomic32<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
210
211 typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
212 request_queue_t mRequestQueue;
213
214 enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2
215 typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
216 request_hash_t mRequestHash;
217
218 handle_t mNextHandle;
219};
220
221#endif // LL_LLQUEUEDTHREAD_H