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
Родитель dda501c04a
Коммит 01cf13549a
3 изменённых файлов: 31 добавлений и 18 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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