PageRenderTime 39ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llqueuedthread.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 213 lines | 140 code | 35 blank | 38 comment | 2 complexity | f652f978bc1c8c6e1955eeaee9193215 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llqueuedthread.h
  3. * @brief
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLQUEUEDTHREAD_H
  27. #define LL_LLQUEUEDTHREAD_H
  28. #include <queue>
  29. #include <string>
  30. #include <map>
  31. #include <set>
  32. #include "llapr.h"
  33. #include "llthread.h"
  34. #include "llsimplehash.h"
  35. //============================================================================
  36. // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small
  37. // It is assumed that LLQueuedThreads are rarely created/destroyed.
  38. class LL_COMMON_API LLQueuedThread : public LLThread
  39. {
  40. //------------------------------------------------------------------------
  41. public:
  42. enum priority_t {
  43. PRIORITY_IMMEDIATE = 0x7FFFFFFF,
  44. PRIORITY_URGENT = 0x40000000,
  45. PRIORITY_HIGH = 0x30000000,
  46. PRIORITY_NORMAL = 0x20000000,
  47. PRIORITY_LOW = 0x10000000,
  48. PRIORITY_LOWBITS = 0x0FFFFFFF,
  49. PRIORITY_HIGHBITS = 0x70000000
  50. };
  51. enum status_t {
  52. STATUS_EXPIRED = -1,
  53. STATUS_UNKNOWN = 0,
  54. STATUS_QUEUED = 1,
  55. STATUS_INPROGRESS = 2,
  56. STATUS_COMPLETE = 3,
  57. STATUS_ABORTED = 4,
  58. STATUS_DELETE = 5
  59. };
  60. enum flags_t {
  61. FLAG_AUTO_COMPLETE = 1,
  62. FLAG_AUTO_DELETE = 2, // child-class dependent
  63. FLAG_ABORT = 4
  64. };
  65. typedef U32 handle_t;
  66. //------------------------------------------------------------------------
  67. public:
  68. class LL_COMMON_API QueuedRequest : public LLSimpleHashEntry<handle_t>
  69. {
  70. friend class LLQueuedThread;
  71. protected:
  72. virtual ~QueuedRequest(); // use deleteRequest()
  73. public:
  74. QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
  75. status_t getStatus()
  76. {
  77. return mStatus;
  78. }
  79. U32 getPriority() const
  80. {
  81. return mPriority;
  82. }
  83. U32 getFlags() const
  84. {
  85. return mFlags;
  86. }
  87. bool higherPriority(const QueuedRequest& second) const
  88. {
  89. if ( mPriority == second.mPriority)
  90. return mHashKey < second.mHashKey;
  91. else
  92. return mPriority > second.mPriority;
  93. }
  94. protected:
  95. status_t setStatus(status_t newstatus)
  96. {
  97. status_t oldstatus = mStatus;
  98. mStatus = newstatus;
  99. return oldstatus;
  100. }
  101. void setFlags(U32 flags)
  102. {
  103. // NOTE: flags are |'d
  104. mFlags |= flags;
  105. }
  106. virtual bool processRequest() = 0; // Return true when request has completed
  107. virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
  108. virtual void deleteRequest(); // Only method to delete a request
  109. void setPriority(U32 pri)
  110. {
  111. // Only do this on a request that is not in a queued list!
  112. mPriority = pri;
  113. };
  114. protected:
  115. LLAtomic32<status_t> mStatus;
  116. U32 mPriority;
  117. U32 mFlags;
  118. };
  119. protected:
  120. struct queued_request_less
  121. {
  122. bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
  123. {
  124. return lhs->higherPriority(*rhs); // higher priority in front of queue (set)
  125. }
  126. };
  127. //------------------------------------------------------------------------
  128. public:
  129. static handle_t nullHandle() { return handle_t(0); }
  130. public:
  131. LLQueuedThread(const std::string& name, bool threaded = true, bool should_pause = false);
  132. virtual ~LLQueuedThread();
  133. virtual void shutdown();
  134. private:
  135. // No copy constructor or copy assignment
  136. LLQueuedThread(const LLQueuedThread&);
  137. LLQueuedThread& operator=(const LLQueuedThread&);
  138. virtual bool runCondition(void);
  139. virtual void run(void);
  140. virtual void startThread(void);
  141. virtual void endThread(void);
  142. virtual void threadedUpdate(void);
  143. protected:
  144. handle_t generateHandle();
  145. bool addRequest(QueuedRequest* req);
  146. S32 processNextRequest(void);
  147. void incQueue();
  148. public:
  149. bool waitForResult(handle_t handle, bool auto_complete = true);
  150. virtual S32 update(F32 max_time_ms);
  151. S32 updateQueue(F32 max_time_ms);
  152. void waitOnPending();
  153. void printQueueStats();
  154. virtual S32 getPending();
  155. bool getThreaded() { return mThreaded ? true : false; }
  156. // Request accessors
  157. status_t getRequestStatus(handle_t handle);
  158. void abortRequest(handle_t handle, bool autocomplete);
  159. void setFlags(handle_t handle, U32 flags);
  160. void setPriority(handle_t handle, U32 priority);
  161. bool completeRequest(handle_t handle);
  162. // This is public for support classes like LLWorkerThread,
  163. // but generally the methods above should be used.
  164. QueuedRequest* getRequest(handle_t handle);
  165. // debug (see source)
  166. bool check();
  167. protected:
  168. BOOL mThreaded; // if false, run on main thread and do updates during update()
  169. BOOL mStarted; // required when mThreaded is false to call startThread() from update()
  170. LLAtomic32<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
  171. typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
  172. request_queue_t mRequestQueue;
  173. enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2
  174. typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
  175. request_hash_t mRequestHash;
  176. handle_t mNextHandle;
  177. };
  178. #endif // LL_LLQUEUEDTHREAD_H