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

/indra/llcommon/llthread.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 498 lines | 315 code | 82 blank | 101 comment | 35 complexity | 999da7c9182cfdbb6fb201de6d52554b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llthread.cpp
  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. #include "linden_common.h"
  26. #include "llapr.h"
  27. #include "apr_portable.h"
  28. #include "llthread.h"
  29. #include "lltimer.h"
  30. #if LL_LINUX || LL_SOLARIS
  31. #include <sched.h>
  32. #endif
  33. //----------------------------------------------------------------------------
  34. // Usage:
  35. // void run_func(LLThread* thread)
  36. // {
  37. // }
  38. // LLThread* thread = new LLThread();
  39. // thread->run(run_func);
  40. // ...
  41. // thread->setQuitting();
  42. // while(!timeout)
  43. // {
  44. // if (thread->isStopped())
  45. // {
  46. // delete thread;
  47. // break;
  48. // }
  49. // }
  50. //
  51. //----------------------------------------------------------------------------
  52. #if !LL_DARWIN
  53. U32 ll_thread_local sThreadID = 0;
  54. #endif
  55. U32 LLThread::sIDIter = 0;
  56. LL_COMMON_API void assert_main_thread()
  57. {
  58. static U32 s_thread_id = LLThread::currentID();
  59. if (LLThread::currentID() != s_thread_id)
  60. {
  61. llerrs << "Illegal execution outside main thread." << llendl;
  62. }
  63. }
  64. //
  65. // Handed to the APR thread creation function
  66. //
  67. void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap)
  68. {
  69. LLThread *threadp = (LLThread *)datap;
  70. #if !LL_DARWIN
  71. sThreadID = threadp->mID;
  72. #endif
  73. // Run the user supplied function
  74. threadp->run();
  75. //llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl;
  76. // We're done with the run function, this thread is done executing now.
  77. threadp->mStatus = STOPPED;
  78. return NULL;
  79. }
  80. LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
  81. mPaused(FALSE),
  82. mName(name),
  83. mAPRThreadp(NULL),
  84. mStatus(STOPPED)
  85. {
  86. mID = ++sIDIter;
  87. // Thread creation probably CAN be paranoid about APR being initialized, if necessary
  88. if (poolp)
  89. {
  90. mIsLocalPool = FALSE;
  91. mAPRPoolp = poolp;
  92. }
  93. else
  94. {
  95. mIsLocalPool = TRUE;
  96. apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
  97. }
  98. mRunCondition = new LLCondition(mAPRPoolp);
  99. mLocalAPRFilePoolp = NULL ;
  100. }
  101. LLThread::~LLThread()
  102. {
  103. shutdown();
  104. if(mLocalAPRFilePoolp)
  105. {
  106. delete mLocalAPRFilePoolp ;
  107. mLocalAPRFilePoolp = NULL ;
  108. }
  109. }
  110. void LLThread::shutdown()
  111. {
  112. // Warning! If you somehow call the thread destructor from itself,
  113. // the thread will die in an unclean fashion!
  114. if (mAPRThreadp)
  115. {
  116. if (!isStopped())
  117. {
  118. // The thread isn't already stopped
  119. // First, set the flag that indicates that we're ready to die
  120. setQuitting();
  121. //llinfos << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << llendl;
  122. // Now wait a bit for the thread to exit
  123. // It's unclear whether I should even bother doing this - this destructor
  124. // should netver get called unless we're already stopped, really...
  125. S32 counter = 0;
  126. const S32 MAX_WAIT = 600;
  127. while (counter < MAX_WAIT)
  128. {
  129. if (isStopped())
  130. {
  131. break;
  132. }
  133. // Sleep for a tenth of a second
  134. ms_sleep(100);
  135. yield();
  136. counter++;
  137. }
  138. }
  139. if (!isStopped())
  140. {
  141. // This thread just wouldn't stop, even though we gave it time
  142. //llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
  143. // Put a stake in its heart.
  144. apr_thread_exit(mAPRThreadp, -1);
  145. return;
  146. }
  147. mAPRThreadp = NULL;
  148. }
  149. delete mRunCondition;
  150. mRunCondition = 0;
  151. if (mIsLocalPool && mAPRPoolp)
  152. {
  153. apr_pool_destroy(mAPRPoolp);
  154. mAPRPoolp = 0;
  155. }
  156. }
  157. void LLThread::start()
  158. {
  159. llassert(isStopped());
  160. // Set thread state to running
  161. mStatus = RUNNING;
  162. apr_status_t status =
  163. apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
  164. if(status == APR_SUCCESS)
  165. {
  166. // We won't bother joining
  167. apr_thread_detach(mAPRThreadp);
  168. }
  169. else
  170. {
  171. mStatus = STOPPED;
  172. llwarns << "failed to start thread " << mName << llendl;
  173. ll_apr_warn_status(status);
  174. }
  175. }
  176. //============================================================================
  177. // Called from MAIN THREAD.
  178. // Request that the thread pause/resume.
  179. // The thread will pause when (and if) it calls checkPause()
  180. void LLThread::pause()
  181. {
  182. if (!mPaused)
  183. {
  184. // this will cause the thread to stop execution as soon as checkPause() is called
  185. mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread
  186. }
  187. }
  188. void LLThread::unpause()
  189. {
  190. if (mPaused)
  191. {
  192. mPaused = 0;
  193. }
  194. wake(); // wake up the thread if necessary
  195. }
  196. // virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
  197. bool LLThread::runCondition(void)
  198. {
  199. // by default, always run. Handling of pause/unpause is done regardless of this function's result.
  200. return true;
  201. }
  202. //============================================================================
  203. // Called from run() (CHILD THREAD).
  204. // Stop thread execution if requested until unpaused.
  205. void LLThread::checkPause()
  206. {
  207. mRunCondition->lock();
  208. // This is in a while loop because the pthread API allows for spurious wakeups.
  209. while(shouldSleep())
  210. {
  211. mRunCondition->wait(); // unlocks mRunCondition
  212. // mRunCondition is locked when the thread wakes up
  213. }
  214. mRunCondition->unlock();
  215. }
  216. //============================================================================
  217. void LLThread::setQuitting()
  218. {
  219. mRunCondition->lock();
  220. if (mStatus == RUNNING)
  221. {
  222. mStatus = QUITTING;
  223. }
  224. mRunCondition->unlock();
  225. wake();
  226. }
  227. // static
  228. U32 LLThread::currentID()
  229. {
  230. return (U32)apr_os_thread_current();
  231. }
  232. // static
  233. void LLThread::yield()
  234. {
  235. #if LL_LINUX || LL_SOLARIS
  236. sched_yield(); // annoyingly, apr_thread_yield is a noop on linux...
  237. #else
  238. apr_thread_yield();
  239. #endif
  240. }
  241. void LLThread::wake()
  242. {
  243. mRunCondition->lock();
  244. if(!shouldSleep())
  245. {
  246. mRunCondition->signal();
  247. }
  248. mRunCondition->unlock();
  249. }
  250. void LLThread::wakeLocked()
  251. {
  252. if(!shouldSleep())
  253. {
  254. mRunCondition->signal();
  255. }
  256. }
  257. //============================================================================
  258. LLMutex::LLMutex(apr_pool_t *poolp) :
  259. mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
  260. {
  261. //if (poolp)
  262. //{
  263. // mIsLocalPool = FALSE;
  264. // mAPRPoolp = poolp;
  265. //}
  266. //else
  267. {
  268. mIsLocalPool = TRUE;
  269. apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
  270. }
  271. apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
  272. }
  273. LLMutex::~LLMutex()
  274. {
  275. #if MUTEX_DEBUG
  276. //bad assertion, the subclass LLSignal might be "locked", and that's OK
  277. //llassert_always(!isLocked()); // better not be locked!
  278. #endif
  279. apr_thread_mutex_destroy(mAPRMutexp);
  280. mAPRMutexp = NULL;
  281. if (mIsLocalPool)
  282. {
  283. apr_pool_destroy(mAPRPoolp);
  284. }
  285. }
  286. void LLMutex::lock()
  287. {
  288. if(isSelfLocked())
  289. { //redundant lock
  290. mCount++;
  291. return;
  292. }
  293. apr_thread_mutex_lock(mAPRMutexp);
  294. #if MUTEX_DEBUG
  295. // Have to have the lock before we can access the debug info
  296. U32 id = LLThread::currentID();
  297. if (mIsLocked[id] != FALSE)
  298. llerrs << "Already locked in Thread: " << id << llendl;
  299. mIsLocked[id] = TRUE;
  300. #endif
  301. #if LL_DARWIN
  302. mLockingThread = LLThread::currentID();
  303. #else
  304. mLockingThread = sThreadID;
  305. #endif
  306. }
  307. void LLMutex::unlock()
  308. {
  309. if (mCount > 0)
  310. { //not the root unlock
  311. mCount--;
  312. return;
  313. }
  314. #if MUTEX_DEBUG
  315. // Access the debug info while we have the lock
  316. U32 id = LLThread::currentID();
  317. if (mIsLocked[id] != TRUE)
  318. llerrs << "Not locked in Thread: " << id << llendl;
  319. mIsLocked[id] = FALSE;
  320. #endif
  321. mLockingThread = NO_THREAD;
  322. apr_thread_mutex_unlock(mAPRMutexp);
  323. }
  324. bool LLMutex::isLocked()
  325. {
  326. apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
  327. if (APR_STATUS_IS_EBUSY(status))
  328. {
  329. return true;
  330. }
  331. else
  332. {
  333. apr_thread_mutex_unlock(mAPRMutexp);
  334. return false;
  335. }
  336. }
  337. bool LLMutex::isSelfLocked()
  338. {
  339. #if LL_DARWIN
  340. return mLockingThread == LLThread::currentID();
  341. #else
  342. return mLockingThread == sThreadID;
  343. #endif
  344. }
  345. U32 LLMutex::lockingThread() const
  346. {
  347. return mLockingThread;
  348. }
  349. //============================================================================
  350. LLCondition::LLCondition(apr_pool_t *poolp) :
  351. LLMutex(poolp)
  352. {
  353. // base class (LLMutex) has already ensured that mAPRPoolp is set up.
  354. apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
  355. }
  356. LLCondition::~LLCondition()
  357. {
  358. apr_thread_cond_destroy(mAPRCondp);
  359. mAPRCondp = NULL;
  360. }
  361. void LLCondition::wait()
  362. {
  363. if (!isLocked())
  364. { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
  365. apr_thread_mutex_lock(mAPRMutexp);
  366. #if MUTEX_DEBUG
  367. // avoid asserts on destruction in non-release builds
  368. U32 id = LLThread::currentID();
  369. mIsLocked[id] = TRUE;
  370. #endif
  371. }
  372. apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
  373. }
  374. void LLCondition::signal()
  375. {
  376. apr_thread_cond_signal(mAPRCondp);
  377. }
  378. void LLCondition::broadcast()
  379. {
  380. apr_thread_cond_broadcast(mAPRCondp);
  381. }
  382. //============================================================================
  383. //----------------------------------------------------------------------------
  384. //static
  385. LLMutex* LLThreadSafeRefCount::sMutex = 0;
  386. //static
  387. void LLThreadSafeRefCount::initThreadSafeRefCount()
  388. {
  389. if (!sMutex)
  390. {
  391. sMutex = new LLMutex(0);
  392. }
  393. }
  394. //static
  395. void LLThreadSafeRefCount::cleanupThreadSafeRefCount()
  396. {
  397. delete sMutex;
  398. sMutex = NULL;
  399. }
  400. //----------------------------------------------------------------------------
  401. LLThreadSafeRefCount::LLThreadSafeRefCount() :
  402. mRef(0)
  403. {
  404. }
  405. LLThreadSafeRefCount::~LLThreadSafeRefCount()
  406. {
  407. if (mRef != 0)
  408. {
  409. llerrs << "deleting non-zero reference" << llendl;
  410. }
  411. }
  412. //============================================================================
  413. LLResponder::~LLResponder()
  414. {
  415. }
  416. //============================================================================