diff options
Diffstat (limited to 'src/bun.js/bindings/webcore/Worker.cpp')
-rw-r--r-- | src/bun.js/bindings/webcore/Worker.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/bun.js/bindings/webcore/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index 4ffbc0684..d92b6e2e5 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -60,6 +60,7 @@ #include "JavaScriptCore/DeferredWorkTimer.h" #include "MessageEvent.h" #include <JavaScriptCore/HashMapImplInlines.h> +#include "BunWorkerGlobalScope.h" namespace WebCore { @@ -176,20 +177,21 @@ ExceptionOr<void> Worker::postMessage(JSC::JSGlobalObject& state, JSC::JSValue m if (message.hasException()) return message.releaseException(); - this->postTaskToWorkerGlobalScope([message = message.releaseReturnValue()](auto& context) { + RefPtr<SerializedScriptValue> result = message.releaseReturnValue(); + + this->postTaskToWorkerGlobalScope([message = WTFMove(result)](auto& context) { Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(context.jsGlobalObject()); bool didFail = false; JSValue value = message->deserialize(*globalObject, globalObject, SerializationErrorMode::NonThrowing, &didFail); - message->deref(); if (didFail) { - globalObject->eventTarget()->dispatchEvent(MessageEvent::create(eventNames().messageerrorEvent, MessageEvent::Init {}, MessageEvent::IsTrusted::Yes)); + globalObject->globalEventScope.dispatchEvent(MessageEvent::create(eventNames().messageerrorEvent, MessageEvent::Init {}, MessageEvent::IsTrusted::Yes)); return; } WebCore::MessageEvent::Init init; init.data = value; - globalObject->eventTarget()->dispatchEvent(MessageEvent::create(eventNames().messageEvent, WTFMove(init), MessageEvent::IsTrusted::Yes)); + globalObject->globalEventScope.dispatchEvent(MessageEvent::create(eventNames().messageEvent, WTFMove(init), MessageEvent::IsTrusted::Yes)); }); return {}; } @@ -229,6 +231,10 @@ void Worker::terminate() bool Worker::hasPendingActivity() const { + if (this->refCount() > 0) { + return true; + } + if (this->m_isOnline) { return !this->m_isClosing; } @@ -241,7 +247,7 @@ void Worker::dispatchEvent(Event& event) if (m_wasTerminated) return; - EventTarget::dispatchEvent(event); + EventTargetWithInlineData::dispatchEvent(event); } #if ENABLE(WEB_RTC) @@ -259,6 +265,7 @@ void Worker::createRTCRtpScriptTransformer(RTCRtpScriptTransform& transform, Mes void Worker::drainEvents() { + Locker lock(this->m_pendingTasksMutex); for (auto& task : m_pendingTasks) postTaskToWorkerGlobalScope(WTFMove(task)); m_pendingTasks.clear(); @@ -277,19 +284,26 @@ void Worker::dispatchOnline(Zig::GlobalObject* workerGlobalObject) }); } + Locker lock(this->m_pendingTasksMutex); + this->m_isOnline = true; auto* thisContext = workerGlobalObject->scriptExecutionContext(); if (!thisContext) { return; } + RELEASE_ASSERT(&thisContext->vm() == &workerGlobalObject->vm()); + RELEASE_ASSERT(thisContext == workerGlobalObject->globalEventScope.scriptExecutionContext()); - if (workerGlobalObject->eventTarget()->hasActiveEventListeners(eventNames().messageEvent)) { + if (workerGlobalObject->globalEventScope.hasActiveEventListeners(eventNames().messageEvent)) { auto tasks = std::exchange(this->m_pendingTasks, {}); + lock.unlockEarly(); for (auto& task : tasks) { task(*thisContext); } } else { auto tasks = std::exchange(this->m_pendingTasks, {}); + lock.unlockEarly(); + thisContext->postTask([tasks = WTFMove(tasks)](auto& ctx) mutable { for (auto& task : tasks) { task(ctx); @@ -334,6 +348,7 @@ void Worker::dispatchExit() void Worker::postTaskToWorkerGlobalScope(Function<void(ScriptExecutionContext&)>&& task) { if (!this->m_isOnline) { + Locker lock(this->m_pendingTasksMutex); this->m_pendingTasks.append(WTFMove(task)); return; } @@ -388,7 +403,7 @@ extern "C" void WebWorker__dispatchError(Zig::GlobalObject* globalObject, Worker init.cancelable = false; init.bubbles = false; - globalObject->eventTarget()->dispatchEvent(ErrorEvent::create(eventNames().errorEvent, init, EventIsTrusted::Yes)); + globalObject->globalEventScope.dispatchEvent(ErrorEvent::create(eventNames().errorEvent, init, EventIsTrusted::Yes)); worker->dispatchError(Bun::toWTFString(message)); } |