/indra/llcommon/llworkerthread.h

https://bitbucket.org/lindenlab/viewer-beta/ · C++ Header · 204 lines · 104 code · 43 blank · 57 comment · 0 complexity · 15db6209ceff5ab600569813cb84f17b MD5 · raw file

  1. /**
  2. * @file llworkerthread.h
  3. *
  4. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #ifndef LL_LLWORKERTHREAD_H
  26. #define LL_LLWORKERTHREAD_H
  27. #include <queue>
  28. #include <string>
  29. #include <map>
  30. #include <set>
  31. #include "llqueuedthread.h"
  32. #include "llapr.h"
  33. #define USE_FRAME_CALLBACK_MANAGER 0
  34. //============================================================================
  35. class LLWorkerClass;
  36. //============================================================================
  37. // Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small
  38. // It is assumed that LLWorkerThreads are rarely created/destroyed.
  39. class LL_COMMON_API LLWorkerThread : public LLQueuedThread
  40. {
  41. friend class LLWorkerClass;
  42. public:
  43. class WorkRequest : public LLQueuedThread::QueuedRequest
  44. {
  45. protected:
  46. virtual ~WorkRequest(); // use deleteRequest()
  47. public:
  48. WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param);
  49. S32 getParam()
  50. {
  51. return mParam;
  52. }
  53. LLWorkerClass* getWorkerClass()
  54. {
  55. return mWorkerClass;
  56. }
  57. /*virtual*/ bool processRequest();
  58. /*virtual*/ void finishRequest(bool completed);
  59. /*virtual*/ void deleteRequest();
  60. private:
  61. LLWorkerClass* mWorkerClass;
  62. S32 mParam;
  63. };
  64. protected:
  65. void clearDeleteList() ;
  66. private:
  67. typedef std::list<LLWorkerClass*> delete_list_t;
  68. delete_list_t mDeleteList;
  69. LLMutex* mDeleteMutex;
  70. public:
  71. LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false);
  72. ~LLWorkerThread();
  73. /*virtual*/ S32 update(F32 max_time_ms);
  74. handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
  75. S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
  76. private:
  77. void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
  78. };
  79. //============================================================================
  80. // This is a base class which any class with worker functions should derive from.
  81. // Example Usage:
  82. // LLMyWorkerClass* foo = new LLMyWorkerClass();
  83. // foo->fetchData(); // calls addWork()
  84. // while(1) // main loop
  85. // {
  86. // if (foo->hasData()) // calls checkWork()
  87. // foo->processData();
  88. // }
  89. //
  90. // WorkerClasses only have one set of work functions. If they need to do multiple
  91. // background tasks, use 'param' to switch amnong them.
  92. // Only one background task can be active at a time (per instance).
  93. // i.e. don't call addWork() if haveWork() returns true
  94. class LL_COMMON_API LLWorkerClass
  95. {
  96. friend class LLWorkerThread;
  97. friend class LLWorkerThread::WorkRequest;
  98. public:
  99. typedef LLWorkerThread::handle_t handle_t;
  100. enum FLAGS
  101. {
  102. WCF_HAVE_WORK = 0x01,
  103. WCF_WORKING = 0x02,
  104. WCF_WORK_FINISHED = 0x10,
  105. WCF_WORK_ABORTED = 0x20,
  106. WCF_DELETE_REQUESTED = 0x40,
  107. WCF_ABORT_REQUESTED = 0x80
  108. };
  109. public:
  110. LLWorkerClass(LLWorkerThread* workerthread, const std::string& name);
  111. virtual ~LLWorkerClass();
  112. // pure virtual, called from WORKER THREAD, returns TRUE if done
  113. virtual bool doWork(S32 param)=0; // Called from WorkRequest::processRequest()
  114. // virtual, called from finishRequest() after completed or aborted
  115. virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
  116. // virtual, returns true if safe to delete the worker
  117. virtual bool deleteOK(); // called from update() (WORK THREAD)
  118. // schedlueDelete(): schedules deletion once aborted or completed
  119. void scheduleDelete();
  120. bool haveWork() { return getFlags(WCF_HAVE_WORK); } // may still be true if aborted
  121. bool isWorking() { return getFlags(WCF_WORKING); }
  122. bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
  123. // setPriority(): changes the priority of a request
  124. void setPriority(U32 priority);
  125. U32 getPriority() { return mRequestPriority; }
  126. const std::string& getName() const { return mWorkerClassName; }
  127. protected:
  128. // called from WORKER THREAD
  129. void setWorking(bool working);
  130. // Call from doWork only to avoid eating up cpu time.
  131. // Returns true if work has been aborted
  132. // yields the current thread and calls mWorkerThread->checkPause()
  133. bool yield();
  134. void setWorkerThread(LLWorkerThread* workerthread);
  135. // addWork(): calls startWork, adds doWork() to queue
  136. void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
  137. // abortWork(): requests that work be aborted
  138. void abortWork(bool autocomplete);
  139. // checkWork(): if doWork is complete or aborted, call endWork() and return true
  140. bool checkWork(bool aborting = false);
  141. private:
  142. void setFlags(U32 flags) { mWorkFlags = mWorkFlags | flags; }
  143. void clearFlags(U32 flags) { mWorkFlags = mWorkFlags & ~flags; }
  144. U32 getFlags() { return mWorkFlags; }
  145. public:
  146. bool getFlags(U32 flags) { return mWorkFlags & flags ? true : false; }
  147. private:
  148. // pure virtuals
  149. virtual void startWork(S32 param)=0; // called from addWork() (MAIN THREAD)
  150. virtual void endWork(S32 param, bool aborted)=0; // called from doWork() (MAIN THREAD)
  151. protected:
  152. LLWorkerThread* mWorkerThread;
  153. std::string mWorkerClassName;
  154. handle_t mRequestHandle;
  155. U32 mRequestPriority; // last priority set
  156. private:
  157. LLMutex mMutex;
  158. LLAtomicU32 mWorkFlags;
  159. };
  160. //============================================================================
  161. #endif // LL_LLWORKERTHREAD_H