Bug 1201051 - Make helper thread initialization report errors rather than crashing r=terrence

This commit is contained in:
Jon Coppeard 2015-09-03 12:08:08 +01:00
parent 6f60980912
commit 3ab5551ed0
3 changed files with 31 additions and 18 deletions

View File

@ -51,11 +51,11 @@ js::DestroyHelperThreadsState()
gHelperThreadState = nullptr;
}
void
bool
js::EnsureHelperThreadsInitialized()
{
MOZ_ASSERT(gHelperThreadState);
gHelperThreadState->ensureInitialized();
return gHelperThreadState->ensureInitialized();
}
static size_t
@ -453,7 +453,7 @@ static const uint32_t HELPER_STACK_SIZE = kDefaultHelperStackSize;
static const uint32_t HELPER_STACK_QUOTA = kDefaultHelperStackQuota;
#endif
void
bool
GlobalHelperThreadState::ensureInitialized()
{
MOZ_ASSERT(CanUseExtraThreads());
@ -462,11 +462,11 @@ GlobalHelperThreadState::ensureInitialized()
AutoLockHelperThreadState lock;
if (threads)
return;
return true;
threads = js_pod_calloc<HelperThread>(threadCount);
if (!threads)
CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized");
return false;
for (size_t i = 0; i < threadCount; i++) {
HelperThread& helper = threads[i];
@ -474,11 +474,15 @@ GlobalHelperThreadState::ensureInitialized()
helper.thread = PR_CreateThread(PR_USER_THREAD,
HelperThread::ThreadMain, &helper,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, HELPER_STACK_SIZE);
if (!helper.thread || !helper.threadData->init())
CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized");
if (!helper.thread || !helper.threadData->init()) {
finishThreads();
return false;
}
}
resetAsmJSFailureState();
return true;
}
GlobalHelperThreadState::GlobalHelperThreadState()
@ -510,12 +514,7 @@ GlobalHelperThreadState::GlobalHelperThreadState()
void
GlobalHelperThreadState::finish()
{
if (threads) {
MOZ_ASSERT(CanUseExtraThreads());
for (size_t i = 0; i < threadCount; i++)
threads[i].destroy();
js_free(threads);
}
finishThreads();
PR_DestroyCondVar(consumerWakeup);
PR_DestroyCondVar(producerWakeup);
@ -525,6 +524,19 @@ GlobalHelperThreadState::finish()
ionLazyLinkList_.clear();
}
void
GlobalHelperThreadState::finishThreads()
{
if (!threads)
return;
MOZ_ASSERT(CanUseExtraThreads());
for (size_t i = 0; i < threadCount; i++)
threads[i].destroy();
js_free(threads);
threads = nullptr;
}
void
GlobalHelperThreadState::lock()
{

View File

@ -103,8 +103,9 @@ class GlobalHelperThreadState
GlobalHelperThreadState();
void ensureInitialized();
bool ensureInitialized();
void finish();
void finishThreads();
void lock();
void unlock();
@ -351,7 +352,7 @@ void
DestroyHelperThreadsState();
// Initialize helper threads unless already initialized.
void
bool
EnsureHelperThreadsInitialized();
// This allows the JS shell to override GetCPUCount() when passed the

View File

@ -283,10 +283,10 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
if (!regexpStack.init())
return false;
js::TlsPerThreadData.set(&mainThread);
if (CanUseExtraThreads() && !EnsureHelperThreadsInitialized())
return false;
if (CanUseExtraThreads())
EnsureHelperThreadsInitialized();
js::TlsPerThreadData.set(&mainThread);
if (!gc.init(maxbytes, maxNurseryBytes))
return false;