00001
00032 #ifndef LL_LLQUEUEDTHREAD_H
00033 #define LL_LLQUEUEDTHREAD_H
00034
00035 #include <queue>
00036 #include <string>
00037 #include <map>
00038 #include <set>
00039
00040 #include "llapr.h"
00041
00042 #include "llthread.h"
00043 #include "llsimplehash.h"
00044
00045
00046
00047
00048
00049 class LLQueuedThread : public LLThread
00050 {
00051
00052 public:
00053 enum priority_t {
00054 PRIORITY_IMMEDIATE = 0x7FFFFFFF,
00055 PRIORITY_URGENT = 0x40000000,
00056 PRIORITY_HIGH = 0x30000000,
00057 PRIORITY_NORMAL = 0x20000000,
00058 PRIORITY_LOW = 0x10000000,
00059 PRIORITY_LOWBITS = 0x0FFFFFFF,
00060 PRIORITY_HIGHBITS = 0x70000000
00061 };
00062 enum status_t {
00063 STATUS_EXPIRED = -1,
00064 STATUS_UNKNOWN = 0,
00065 STATUS_QUEUED = 1,
00066 STATUS_INPROGRESS = 2,
00067 STATUS_COMPLETE = 3,
00068 STATUS_ABORTED = 4,
00069 STATUS_DELETE = 5
00070 };
00071 enum flags_t {
00072 FLAG_AUTO_COMPLETE = 1,
00073 FLAG_AUTO_DELETE = 2,
00074 FLAG_ABORT = 4
00075 };
00076
00077 typedef U32 handle_t;
00078
00079
00080 public:
00081
00082 class QueuedRequest : public LLSimpleHashEntry<handle_t>
00083 {
00084 friend class LLQueuedThread;
00085
00086 protected:
00087 virtual ~QueuedRequest();
00088
00089 public:
00090 QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
00091
00092 status_t getStatus()
00093 {
00094 return mStatus;
00095 }
00096 U32 getPriority() const
00097 {
00098 return mPriority;
00099 }
00100 U32 getFlags() const
00101 {
00102 return mFlags;
00103 }
00104 bool higherPriority(const QueuedRequest& second) const
00105 {
00106 if ( mPriority == second.mPriority)
00107 return mHashKey < second.mHashKey;
00108 else
00109 return mPriority > second.mPriority;
00110 }
00111
00112 protected:
00113 status_t setStatus(status_t newstatus)
00114 {
00115 status_t oldstatus = mStatus;
00116 mStatus = newstatus;
00117 return oldstatus;
00118 }
00119 void setFlags(U32 flags)
00120 {
00121
00122 mFlags |= flags;
00123 }
00124
00125 virtual bool processRequest() = 0;
00126 virtual void finishRequest(bool completed);
00127 virtual void deleteRequest();
00128
00129 void setPriority(U32 pri)
00130 {
00131
00132 mPriority = pri;
00133 };
00134
00135 protected:
00136 LLAtomic32<status_t> mStatus;
00137 U32 mPriority;
00138 U32 mFlags;
00139 };
00140
00141 protected:
00142 struct queued_request_less
00143 {
00144 bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
00145 {
00146 return lhs->higherPriority(*rhs);
00147 }
00148 };
00149
00150
00151
00152 public:
00153 static handle_t nullHandle() { return handle_t(0); }
00154
00155 public:
00156 LLQueuedThread(const std::string& name, bool threaded = true);
00157 virtual ~LLQueuedThread();
00158 virtual void shutdown();
00159
00160 private:
00161
00162 LLQueuedThread(const LLQueuedThread&);
00163 LLQueuedThread& operator=(const LLQueuedThread&);
00164
00165 virtual bool runCondition(void);
00166 virtual void run(void);
00167
00168 protected:
00169 handle_t generateHandle();
00170 bool addRequest(QueuedRequest* req);
00171 S32 processNextRequest(void);
00172 void incQueue();
00173
00174 public:
00175 bool waitForResult(handle_t handle, bool auto_complete = true);
00176
00177 virtual S32 update(U32 max_time_ms);
00178 S32 updateQueue(U32 max_time_ms);
00179
00180 void waitOnPending();
00181 void printQueueStats();
00182
00183 S32 getPending();
00184 bool getThreaded() { return mThreaded ? true : false; }
00185
00186
00187 status_t getRequestStatus(handle_t handle);
00188 void abortRequest(handle_t handle, bool autocomplete);
00189 void setFlags(handle_t handle, U32 flags);
00190 void setPriority(handle_t handle, U32 priority);
00191 bool completeRequest(handle_t handle);
00192
00193
00194 QueuedRequest* getRequest(handle_t handle);
00195
00196
00197 bool check();
00198
00199 protected:
00200 BOOL mThreaded;
00201 LLAtomic32<BOOL> mIdleThread;
00202
00203 typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
00204 request_queue_t mRequestQueue;
00205
00206 enum { REQUEST_HASH_SIZE = 512 };
00207 typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
00208 request_hash_t mRequestHash;
00209
00210 handle_t mNextHandle;
00211 };
00212
00213 #endif // LL_LLQUEUEDTHREAD_H