aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/webcore/Worker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings/webcore/Worker.cpp')
-rw-r--r--src/bun.js/bindings/webcore/Worker.cpp29
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));
}