llthread.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * @file llthread.h
  3. * @brief Base classes for thread, mutex and condition handling.
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2004-2009, 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_LLTHREAD_H
  33. #define LL_LLTHREAD_H
  34. #if TRACY_ENABLE
  35. # include <list>
  36. #endif
  37. #include "boost/thread.hpp"
  38. #include "llapp.h"
  39. #include "llmutex.h"
  40. #include "llrefcount.h"
  41. bool is_main_thread();
  42. void assert_main_thread();
  43. class LLThread
  44. {
  45. friend class LLMutex;
  46. protected:
  47. LOG_CLASS(LLThread);
  48. public:
  49. typedef boost::thread::id id_t;
  50. typedef enum e_thread_status
  51. {
  52. STOPPED = 0, // Thread is not running: not started or exited run()
  53. RUNNING = 1, // Thread is currently running
  54. QUITTING = 2 // Someone wants this thread to quit
  55. } EThreadStatus;
  56. LLThread(const std::string& name);
  57. // Warning ! You almost NEVER want to destroy a thread unless it is in the
  58. // STOPPED state.
  59. virtual ~LLThread();
  60. virtual void shutdown(); // Stops the thread
  61. LL_INLINE bool isRunning() const { return mStatus == RUNNING; }
  62. LL_INLINE bool isQuitting() const { return mStatus == QUITTING; }
  63. LL_INLINE bool isStopped() const { return mStatus == STOPPED; }
  64. // PAUSE / RESUME functionality. See source code for important usage notes.
  65. // Called from MAIN THREAD.
  66. void pause();
  67. void unpause();
  68. LL_INLINE bool isPaused() { return isStopped() || mPaused; }
  69. // Cause the thread to wake up and check its condition
  70. void wake();
  71. // Same as above, but to be used when the condition is already locked.
  72. void wakeLocked();
  73. // Called from run() (CHILD THREAD). Pause the thread if requested until
  74. // unpaused.
  75. void checkPause();
  76. // This kicks off the thread
  77. void start();
  78. // Note: returns a "not a thread" value until threadRun() is called.
  79. LL_INLINE id_t getID() const { return mID; }
  80. // Sets the maximum number of retries after a thread run() threw an
  81. // exception
  82. LL_INLINE void setRetries(U32 n) { mRetries = n + 1; }
  83. // Static because it can be called by the main thread, which does not have
  84. // an LLThread data structure.
  85. static void yield();
  86. // Returns the ID of the current thread
  87. static id_t currentID();
  88. static U64 thisThreadIdHash();
  89. protected:
  90. void setQuitting();
  91. // Virtual function overridden by subclass; this is called when the thread
  92. // runs
  93. virtual void run() = 0;
  94. // Virtual predicate function: returns true if the thread should wake up,
  95. // false if it should sleep.
  96. virtual bool runCondition();
  97. // Lock/unlock Run Condition: use around modification of any variable used
  98. // in runCondition()
  99. LL_INLINE void lockData() { mDataLock->lock(); }
  100. LL_INLINE void unlockData() { mDataLock->unlock(); }
  101. // This is the predicate that decides whether the thread should sleep.
  102. // It should only be called with mDataLock locked, since the virtual
  103. // runCondition() function may need to access data structures that are
  104. // thread-unsafe.
  105. // To avoid spurious signals (and the associated context switches) when the
  106. // condition may or may not have changed, you can do the following:
  107. // mDataLock->lock();
  108. // if (!shouldSleep())
  109. // mRunCondition->signal();
  110. // mDataLock->unlock();
  111. LL_INLINE bool shouldSleep()
  112. {
  113. return mStatus == RUNNING && (isPaused() || !runCondition());
  114. }
  115. private:
  116. // Paranoid (actually needed) check for spuriously deleted threads.
  117. static bool isThreadLive(LLThread* threadp);
  118. void threadRun();
  119. protected:
  120. LLMutex* mDataLock;
  121. class LLCondition* mRunCondition;
  122. boost::thread* mThreadp;
  123. std::string mName;
  124. id_t mID;
  125. EThreadStatus mStatus;
  126. private:
  127. // For termination in case of issues
  128. typedef boost::thread::native_handle_type handle_t;
  129. handle_t mNativeHandle;
  130. #if TRACY_ENABLE
  131. const char* mThreadName;
  132. #endif
  133. U32 mRetries;
  134. bool mPaused;
  135. bool mNeedsAffinity;
  136. };
  137. #if TRACY_ENABLE
  138. extern std::list<std::string> gTracyThreadNames;
  139. extern LLMutex gTracyThreadNamesLock;
  140. #endif
  141. #endif // LL_LLTHREAD_H