diff -r 000000000000 -r 6474c204b198 security/manager/ssl/src/nsPSMBackgroundThread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/manager/ssl/src/nsPSMBackgroundThread.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsPSMBackgroundThread.h" +#include "nsThreadUtils.h" + +using namespace mozilla; + +void nsPSMBackgroundThread::nsThreadRunner(void *arg) +{ + nsPSMBackgroundThread *self = static_cast(arg); + PR_SetCurrentThreadName(self->mName.BeginReading()); + self->Run(); +} + +nsPSMBackgroundThread::nsPSMBackgroundThread() +: mThreadHandle(nullptr), + mMutex("nsPSMBackgroundThread.mMutex"), + mCond(mMutex, "nsPSMBackgroundThread.mCond"), + mExitState(ePSMThreadRunning) +{ +} + +nsresult nsPSMBackgroundThread::startThread(const nsCSubstring & name) +{ + mName = name; + + mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsThreadRunner, static_cast(this), + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + + NS_ASSERTION(mThreadHandle, "Could not create nsPSMBackgroundThread\n"); + + if (!mThreadHandle) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + +nsPSMBackgroundThread::~nsPSMBackgroundThread() +{ +} + +bool +nsPSMBackgroundThread::exitRequested(const MutexAutoLock & /*proofOfLock*/) const +{ + return exitRequestedNoLock(); +} + +nsresult +nsPSMBackgroundThread::postStoppedEventToMainThread( + MutexAutoLock const & /*proofOfLock*/) +{ + NS_ASSERTION(PR_GetCurrentThread() == mThreadHandle, + "Background thread stopped from another thread"); + + mExitState = ePSMThreadStopped; + // requestExit is waiting for an event, so give it one. + return NS_DispatchToMainThread(new nsRunnable()); +} + +void nsPSMBackgroundThread::requestExit() +{ + NS_ASSERTION(NS_IsMainThread(), + "nsPSMBackgroundThread::requestExit called off main thread."); + + if (!mThreadHandle) + return; + + { + MutexAutoLock threadLock(mMutex); + if (mExitState < ePSMThreadStopRequested) { + mExitState = ePSMThreadStopRequested; + mCond.NotifyAll(); + } + } + + nsCOMPtr mainThread = do_GetCurrentThread(); + for (;;) { + { + MutexAutoLock threadLock(mMutex); + if (mExitState == ePSMThreadStopped) + break; + } + NS_ProcessPendingEvents(mainThread, PR_MillisecondsToInterval(50)); + } + + PR_JoinThread(mThreadHandle); + mThreadHandle = nullptr; +}