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);
|
||||
}
|
||||
|
||||
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
|
||||
EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
||||
@ -2848,6 +2862,14 @@ EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!args[0].toString()->ensureLinear(cx))
|
||||
return false;
|
||||
|
||||
if (!workerThreadsLock) {
|
||||
workerThreadsLock = PR_NewLock();
|
||||
if (!workerThreadsLock) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JSLinearString* str = &args[0].toString()->asLinear();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
AutoLockWorkerThreads alwt;
|
||||
if (!workerThreads.append(thread)) {
|
||||
ReportOutOfMemory(cx);
|
||||
PR_JoinThread(thread);
|
||||
@ -3068,6 +3091,34 @@ ScheduleWatchdog(JSRuntime* rt, double t)
|
||||
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
|
||||
CancelExecution(JSRuntime* rt)
|
||||
{
|
||||
@ -7010,9 +7061,7 @@ main(int argc, char** argv, char** envp)
|
||||
|
||||
KillWatchdog(rt);
|
||||
|
||||
MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
|
||||
for (size_t i = 0; i < workerThreads.length(); i++)
|
||||
PR_JoinThread(workerThreads[i]);
|
||||
KillWorkerThreads();
|
||||
|
||||
DestructSharedArrayBufferMailbox();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user