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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llqueuedthread.h
  3.  * @brief
  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_LLQUEUEDTHREAD_H
  33. #define LL_LLQUEUEDTHREAD_H
  34. #include <queue>
  35. #include <string>
  36. #include <map>
  37. #include <set>
  38. #include "llapr.h"
  39. #include "llthread.h"
  40. #include "llsimplehash.h"
  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. class LL_COMMON_API LLQueuedThread : public LLThread
  45. {
  46. //------------------------------------------------------------------------
  47. public:
  48. enum priority_t {
  49. PRIORITY_IMMEDIATE = 0x7FFFFFFF,
  50. PRIORITY_URGENT =    0x40000000,
  51. PRIORITY_HIGH =      0x30000000,
  52. PRIORITY_NORMAL =    0x20000000,
  53. PRIORITY_LOW =       0x10000000,
  54. PRIORITY_LOWBITS =   0x0FFFFFFF,
  55. PRIORITY_HIGHBITS =  0x70000000
  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_ABORTED = 4,
  64. STATUS_DELETE = 5
  65. };
  66. enum flags_t {
  67. FLAG_AUTO_COMPLETE = 1,
  68. FLAG_AUTO_DELETE = 2, // child-class dependent
  69. FLAG_ABORT = 4
  70. };
  71. typedef U32 handle_t;
  72. //------------------------------------------------------------------------
  73. public:
  74. class LL_COMMON_API QueuedRequest : public LLSimpleHashEntry<handle_t>
  75. {
  76. friend class LLQueuedThread;
  77. protected:
  78. virtual ~QueuedRequest(); // use deleteRequest()
  79. public:
  80. QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
  81. status_t getStatus()
  82. {
  83. return mStatus;
  84. }
  85. U32 getPriority() const
  86. {
  87. return mPriority;
  88. }
  89. U32 getFlags() const
  90. {
  91. return mFlags;
  92. }
  93. bool higherPriority(const QueuedRequest& second) const
  94. {
  95. if ( mPriority == second.mPriority)
  96. return mHashKey < second.mHashKey;
  97. else
  98. return mPriority > second.mPriority;
  99. }
  100. protected:
  101. status_t setStatus(status_t newstatus)
  102. {
  103. status_t oldstatus = mStatus;
  104. mStatus = newstatus;
  105. return oldstatus;
  106. }
  107. void setFlags(U32 flags)
  108. {
  109. // NOTE: flags are |'d
  110. mFlags |= flags;
  111. }
  112. virtual bool processRequest() = 0; // Return true when request has completed
  113. virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
  114. virtual void deleteRequest(); // Only method to delete a request
  115. void setPriority(U32 pri)
  116. {
  117. // Only do this on a request that is not in a queued list!
  118. mPriority = pri;
  119. };
  120. protected:
  121. LLAtomic32<status_t> mStatus;
  122. U32 mPriority;
  123. U32 mFlags;
  124. };
  125. protected:
  126. struct queued_request_less
  127. {
  128. bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
  129. {
  130. return lhs->higherPriority(*rhs); // higher priority in front of queue (set)
  131. }
  132. };
  133. //------------------------------------------------------------------------
  134. public:
  135. static handle_t nullHandle() { return handle_t(0); }
  136. public:
  137. LLQueuedThread(const std::string& name, bool threaded = true);
  138. virtual ~LLQueuedThread();
  139. virtual void shutdown();
  140. private:
  141. // No copy constructor or copy assignment
  142. LLQueuedThread(const LLQueuedThread&);
  143. LLQueuedThread& operator=(const LLQueuedThread&);
  144. virtual bool runCondition(void);
  145. virtual void run(void);
  146. virtual void startThread(void);
  147. virtual void endThread(void);
  148. virtual void threadedUpdate(void);
  149. protected:
  150. handle_t generateHandle();
  151. bool addRequest(QueuedRequest* req);
  152. S32  processNextRequest(void);
  153. void incQueue();
  154. public:
  155. bool waitForResult(handle_t handle, bool auto_complete = true);
  156. virtual S32 update(U32 max_time_ms);
  157. S32 updateQueue(U32 max_time_ms);
  158. void waitOnPending();
  159. void printQueueStats();
  160. S32 getPending();
  161. bool getThreaded() { return mThreaded ? true : false; }
  162. // Request accessors
  163. status_t getRequestStatus(handle_t handle);
  164. void abortRequest(handle_t handle, bool autocomplete);
  165. void setFlags(handle_t handle, U32 flags);
  166. void setPriority(handle_t handle, U32 priority);
  167. bool completeRequest(handle_t handle);
  168. // This is public for support classes like LLWorkerThread,
  169. // but generally the methods above should be used.
  170. QueuedRequest* getRequest(handle_t handle);
  171. // debug (see source)
  172. bool check();
  173. protected:
  174. BOOL mThreaded;  // if false, run on main thread and do updates during update()
  175. BOOL mStarted;  // required when mThreaded is false to call startThread() from update()
  176. LLAtomic32<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
  177. typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
  178. request_queue_t mRequestQueue;
  179. enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2
  180. typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
  181. request_hash_t mRequestHash;
  182. handle_t mNextHandle;
  183. };
  184. #endif // LL_LLQUEUEDTHREAD_H