зеркало из https://github.com/mozilla/gecko-dev.git
91 строка
2.3 KiB
C++
91 строка
2.3 KiB
C++
/* 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<nsPSMBackgroundThread *>(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<void*>(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<nsIThread> mainThread = do_GetCurrentThread();
|
|
for (;;) {
|
|
{
|
|
MutexAutoLock threadLock(mMutex);
|
|
if (mExitState == ePSMThreadStopped)
|
|
break;
|
|
}
|
|
NS_ProcessPendingEvents(mainThread, PR_MillisecondsToInterval(50));
|
|
}
|
|
|
|
PR_JoinThread(mThreadHandle);
|
|
mThreadHandle = nullptr;
|
|
}
|