diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index c68aa5d99a..55fb3d4084 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -861,6 +861,7 @@ if(NOT WIN32) -Wno-unused-function -Wno-c++23-lambda-attributes -Wno-nullability-completeness + -Wmisleading-indentation -Werror ) else() diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp index 3a5f32aba1..44d55768bc 100644 --- a/src/bun.js/bindings/webcore/MessagePort.cpp +++ b/src/bun.js/bindings/webcore/MessagePort.cpp @@ -44,6 +44,7 @@ #include #include #include +#include extern "C" void Bun__eventLoop__incrementRefConcurrently(void* bunVM, int delta); @@ -238,7 +239,11 @@ void MessagePort::close() return; m_isDetached = true; - MessagePortChannelProvider::singleton().messagePortClosed(m_identifier); + WTF::ensureOnMainThread( + [this]() { + MessagePortChannelProvider::singleton().messagePortClosed(m_identifier); + } + ); removeAllEventListeners(); } @@ -339,13 +344,29 @@ JSValue MessagePort::tryTakeMessage(JSGlobalObject* lexicalGlobalObject) if (!context || context->activeDOMObjectsAreSuspended() || !isEntangled()) return jsUndefined(); - std::optional messageWithPorts = MessagePortChannelProvider::fromContext(*context).tryTakeMessageForPort(m_identifier); + std::optional result; + BinarySemaphore semaphore; - if (!messageWithPorts) + auto callback = [&](std::optional&& messageWithPorts) { + printf("got message\n"); + result = WTFMove(messageWithPorts); + semaphore.signal(); + }; + + WTF::ensureOnMainThread([identifier = m_identifier, callback = WTFMove(callback), context]() mutable { + printf("taking message on main thread\n"); + MessagePortChannelProvider::fromContext(*context).tryTakeMessageForPort(identifier, WTFMove(callback)); + }); + + printf("waiting for message\n"); + + semaphore.wait(); + + if (!result) return jsUndefined(); - auto ports = MessagePort::entanglePorts(*context, WTFMove(messageWithPorts->transferredPorts)); - auto message = messageWithPorts->message.releaseNonNull(); + auto ports = MessagePort::entanglePorts(*context, WTFMove(result->transferredPorts)); + auto message = result->message.releaseNonNull(); return message->deserialize(*lexicalGlobalObject, lexicalGlobalObject, WTFMove(ports), SerializationErrorMode::NonThrowing); } @@ -510,4 +531,4 @@ void MessagePort::jsUnref(JSGlobalObject* lexicalGlobalObject) } } -} // namespace WebCore +} // namespace WebCore \ No newline at end of file diff --git a/src/bun.js/bindings/webcore/MessagePortChannel.cpp b/src/bun.js/bindings/webcore/MessagePortChannel.cpp index 8b5aa694a6..d13f363034 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannel.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannel.cpp @@ -185,17 +185,21 @@ bool MessagePortChannel::hasAnyMessagesPendingOrInFlight() const return m_messageBatchesInFlight || !m_pendingMessages[0].isEmpty() || !m_pendingMessages[1].isEmpty(); } -std::optional MessagePortChannel::tryTakeMessageForPort(const MessagePortIdentifier port) +void MessagePortChannel::tryTakeMessageForPort(const MessagePortIdentifier port, CompletionHandler&&)>&& callback) { + ASSERT(isMainThread()); + ASSERT(port == m_ports[0] || port == m_ports[1]); size_t i = port == m_ports[0] ? 0 : 1; - if (m_pendingMessages[i].isEmpty()) - return std::nullopt; + if (m_pendingMessages[i].isEmpty()) { + callback(std::nullopt); + return; + } auto message = m_pendingMessages[i].first(); m_pendingMessages[i].removeAt(0); - return WTFMove(message); + callback(WTFMove(message)); } } // namespace WebCore \ No newline at end of file diff --git a/src/bun.js/bindings/webcore/MessagePortChannel.h b/src/bun.js/bindings/webcore/MessagePortChannel.h index 839a0e5490..d6d349e9c9 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannel.h +++ b/src/bun.js/bindings/webcore/MessagePortChannel.h @@ -56,7 +56,7 @@ public: bool postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget); void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler&&, CompletionHandler&&)>&&); - std::optional tryTakeMessageForPort(const MessagePortIdentifier); + void tryTakeMessageForPort(const MessagePortIdentifier, CompletionHandler&&)>&&); WEBCORE_EXPORT bool hasAnyMessagesPendingOrInFlight() const; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProvider.h b/src/bun.js/bindings/webcore/MessagePortChannelProvider.h index 5e647e43d0..416a2279e0 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProvider.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelProvider.h @@ -59,7 +59,7 @@ public: virtual void messagePortClosed(const MessagePortIdentifier& local) = 0; virtual void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler&&, CompletionHandler&&)>&&) = 0; - virtual std::optional tryTakeMessageForPort(const MessagePortIdentifier&) = 0; + virtual void tryTakeMessageForPort(const MessagePortIdentifier&, CompletionHandler&&)>&&) = 0; virtual void postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget) = 0; }; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp index f38cf852da..ba84b4fc49 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp @@ -96,9 +96,9 @@ void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIde }); } -std::optional MessagePortChannelProviderImpl::tryTakeMessageForPort(const MessagePortIdentifier& port) +void MessagePortChannelProviderImpl::tryTakeMessageForPort(const MessagePortIdentifier& port, CompletionHandler&&)>&& callback) { - return m_registry.tryTakeMessageForPort(port); + m_registry.tryTakeMessageForPort(port, WTFMove(callback)); } } // namespace WebCore \ No newline at end of file diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h index 444e5430c4..17f756960e 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.h @@ -42,7 +42,7 @@ private: void messagePortClosed(const MessagePortIdentifier& local) final; void postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget) final; void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler&&, CompletionHandler&&)>&&) final; - std::optional tryTakeMessageForPort(const MessagePortIdentifier&) final; + void tryTakeMessageForPort(const MessagePortIdentifier&, CompletionHandler&&)>&&) final; MessagePortChannelRegistry m_registry; }; diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp index d443d1762f..54a31fdcf0 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.cpp @@ -159,25 +159,25 @@ void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentif channel->takeAllMessagesForPort(port, WTFMove(callback)); } -std::optional MessagePortChannelRegistry::tryTakeMessageForPort(const MessagePortIdentifier& port) +void MessagePortChannelRegistry::tryTakeMessageForPort(const MessagePortIdentifier& port, CompletionHandler&&)>&& callback) { - // Bun calls this from worker threads - // ASSERT(isMainThread()); + ASSERT(isMainThread()); // LOG(MessagePorts, "Registry: Trying to take a message for MessagePort %s", port.logString().utf8().data()); // The channel might be gone if the remote side was closed. auto* channel = m_openChannels.get(port); - if (!channel) - return std::nullopt; + if (!channel) { + callback(std::nullopt); + return; + } - return channel->tryTakeMessageForPort(port); + channel->tryTakeMessageForPort(port, WTFMove(callback)); } MessagePortChannel* MessagePortChannelRegistry::existingChannelContainingPort(const MessagePortIdentifier& port) { - // Bun calls this from worker threads - // ASSERT(isMainThread()); + ASSERT(isMainThread()); return m_openChannels.get(port); } diff --git a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h index 0eed464aee..c041081d42 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h +++ b/src/bun.js/bindings/webcore/MessagePortChannelRegistry.h @@ -49,7 +49,7 @@ public: WEBCORE_EXPORT void didCloseMessagePort(const MessagePortIdentifier& local); WEBCORE_EXPORT bool didPostMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget); WEBCORE_EXPORT void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler&&, CompletionHandler&&)>&&); - WEBCORE_EXPORT std::optional tryTakeMessageForPort(const MessagePortIdentifier&); + WEBCORE_EXPORT void tryTakeMessageForPort(const MessagePortIdentifier&, CompletionHandler&&)>&&); WEBCORE_EXPORT MessagePortChannel* existingChannelContainingPort(const MessagePortIdentifier&); diff --git a/src/codegen/generate-jssink.ts b/src/codegen/generate-jssink.ts index 6727da7bcf..837ef0359e 100644 --- a/src/codegen/generate-jssink.ts +++ b/src/codegen/generate-jssink.ts @@ -357,8 +357,9 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic templ += ` void ${className}::ref() { - if (!m_sinkPtr) - return; + if (!m_sinkPtr) { + return; + } m_refCount++; if (m_refCount == 1) { @@ -367,14 +368,14 @@ JSC_DEFINE_HOST_FUNCTION(functionStartDirectStream, (JSC::JSGlobalObject * lexic } void ${className}::unref() { - if (!m_sinkPtr) - return; + if (!m_sinkPtr) { + return; + } - m_refCount = std::max(0, m_refCount - 1); - if (!m_refCount) - { + m_refCount = std::max(0, m_refCount - 1); + if (!m_refCount) { ${name}__updateRef(m_sinkPtr, false); - } + } } JSC_DEFINE_HOST_FUNCTION(${name}__ref, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame *callFrame))