mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
Bug 1243248 - Fix shell-only workerThreads races. r=jonco
--HG-- extra : rebase_source : 1cf8f7b9cc28c56a848df9e170e8d79daf1922e3
This commit is contained in:
parent
a7cc7fa9ec
commit
1c3e9791a8
@ -2829,7 +2829,21 @@ WorkerMain(void* arg)
|
|||||||
js_delete(input);
|
js_delete(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<PRThread*, 0, SystemAllocPolicy> workerThreads;
|
// Workers can spawn other workers, so we need a lock to access workerThreads.
|
||||||
|
static PRLock* workerThreadsLock = nullptr;
|
||||||
|
static Vector<PRThread*, 0, SystemAllocPolicy> workerThreads;
|
||||||
|
|
||||||
|
class MOZ_RAII AutoLockWorkerThreads
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoLockWorkerThreads() {
|
||||||
|
MOZ_ASSERT(workerThreadsLock);
|
||||||
|
PR_Lock(workerThreadsLock);
|
||||||
|
}
|
||||||
|
~AutoLockWorkerThreads() {
|
||||||
|
PR_Unlock(workerThreadsLock);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
||||||
@ -2848,6 +2862,14 @@ EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
|||||||
if (!args[0].toString()->ensureLinear(cx))
|
if (!args[0].toString()->ensureLinear(cx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!workerThreadsLock) {
|
||||||
|
workerThreadsLock = PR_NewLock();
|
||||||
|
if (!workerThreadsLock) {
|
||||||
|
ReportOutOfMemory(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JSLinearString* str = &args[0].toString()->asLinear();
|
JSLinearString* str = &args[0].toString()->asLinear();
|
||||||
|
|
||||||
char16_t* chars = (char16_t*) js_malloc(str->length() * sizeof(char16_t));
|
char16_t* chars = (char16_t*) js_malloc(str->length() * sizeof(char16_t));
|
||||||
@ -2872,6 +2894,7 @@ EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoLockWorkerThreads alwt;
|
||||||
if (!workerThreads.append(thread)) {
|
if (!workerThreads.append(thread)) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
PR_JoinThread(thread);
|
PR_JoinThread(thread);
|
||||||
@ -3068,6 +3091,34 @@ ScheduleWatchdog(JSRuntime* rt, double t)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
KillWorkerThreads()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
|
||||||
|
|
||||||
|
if (!workerThreadsLock) {
|
||||||
|
MOZ_ASSERT(workerThreads.empty());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// We need to leave the AutoLockWorkerThreads scope before we call
|
||||||
|
// PR_JoinThread, to avoid deadlocks when AutoLockWorkerThreads is
|
||||||
|
// used by the worker thread.
|
||||||
|
PRThread* thread;
|
||||||
|
{
|
||||||
|
AutoLockWorkerThreads alwt;
|
||||||
|
if (workerThreads.empty())
|
||||||
|
break;
|
||||||
|
thread = workerThreads.popCopy();
|
||||||
|
}
|
||||||
|
PR_JoinThread(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
PR_DestroyLock(workerThreadsLock);
|
||||||
|
workerThreadsLock = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CancelExecution(JSRuntime* rt)
|
CancelExecution(JSRuntime* rt)
|
||||||
{
|
{
|
||||||
@ -7010,9 +7061,7 @@ main(int argc, char** argv, char** envp)
|
|||||||
|
|
||||||
KillWatchdog(rt);
|
KillWatchdog(rt);
|
||||||
|
|
||||||
MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
|
KillWorkerThreads();
|
||||||
for (size_t i = 0; i < workerThreads.length(); i++)
|
|
||||||
PR_JoinThread(workerThreads[i]);
|
|
||||||
|
|
||||||
DestructSharedArrayBufferMailbox();
|
DestructSharedArrayBufferMailbox();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user