Diff
Modified: trunk/Source/WebCore/ChangeLog (283294 => 283295)
--- trunk/Source/WebCore/ChangeLog 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/ChangeLog 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1,3 +1,91 @@
+2021-09-29 Chris Dumez <[email protected]>
+
+ Add support for running service workers on the main thread
+ https://bugs.webkit.org/show_bug.cgi?id=230649
+
+ Reviewed by Alex Christensen.
+
+ Add support for running service workers on the main thread (off by default).
+
+ This is to support use cases where the InjectedBundle needs to have access
+ to a service worker's JS global object and script it. It wouldn't be practical
+ in such cases to have the service worker running off the main thread. Note that
+ this is not meant to be used for service workers in general, only for some very
+ specific service workers that require interaction with WebKit's injected bundle.
+
+ * Headers.cmake:
+ * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+ (WebCore::IDBClient::IDBConnectionProxy::forgetActivityForCurrentThread):
+ * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion):
+ * WebCore.xcodeproj/project.pbxproj:
+ * inspector/WorkerDebugger.cpp:
+ (WebCore::WorkerDebugger::runEventLoopWhilePaused):
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+ * page/PerformanceUserTiming.cpp:
+ (WebCore::PerformanceUserTiming::convertMarkToTimestamp const):
+ * workers/WorkerOrWorkletGlobalScope.h:
+ * workers/WorkerOrWorkletScriptController.cpp:
+ (WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously):
+ * workers/WorkerOrWorkletScriptController.h:
+ * workers/WorkerOrWorkletThread.cpp:
+ (WebCore::constructRunLoop):
+ (WebCore::WorkerOrWorkletThread::WorkerOrWorkletThread):
+ (WebCore::WorkerOrWorkletThread::startRunningDebuggerTasks):
+ (WebCore::WorkerOrWorkletThread::runEventLoop):
+ (WebCore::WorkerOrWorkletThread::workerOrWorkletThread):
+ (WebCore::WorkerOrWorkletThread::stop):
+ (WebCore::WorkerOrWorkletThread::suspend):
+ (WebCore::WorkerOrWorkletThread::resume):
+ * workers/WorkerOrWorkletThread.h:
+ * workers/WorkerRunLoop.cpp:
+ (WebCore::ModePredicate::operator() const):
+ (WebCore::WorkerDedicatedRunLoop::WorkerDedicatedRunLoop):
+ (WebCore::WorkerDedicatedRunLoop::~WorkerDedicatedRunLoop):
+ (WebCore::RunLoopSetup::RunLoopSetup):
+ (WebCore::WorkerDedicatedRunLoop::run):
+ (WebCore::WorkerDedicatedRunLoop::runInDebuggerMode):
+ (WebCore::WorkerDedicatedRunLoop::runInMode):
+ (WebCore::WorkerDedicatedRunLoop::runCleanupTasks):
+ (WebCore::WorkerDedicatedRunLoop::terminate):
+ (WebCore::WorkerDedicatedRunLoop::postTaskAndTerminate):
+ (WebCore::WorkerDedicatedRunLoop::postTaskForMode):
+ (WebCore::WorkerDedicatedRunLoop::Task::performTask):
+ (WebCore::WorkerDedicatedRunLoop::Task::Task):
+ (WebCore::WorkerMainRunLoop::WorkerMainRunLoop):
+ (WebCore::WorkerMainRunLoop::setGlobalScope):
+ (WebCore::WorkerMainRunLoop::postTaskAndTerminate):
+ (WebCore::WorkerMainRunLoop::postTaskForMode):
+ (WebCore::WorkerMainRunLoop::runInMode):
+ * workers/WorkerRunLoop.h:
+ (WebCore::WorkerRunLoop::createUniqueId):
+ (isType):
+ * workers/WorkerThread.cpp:
+ (WebCore::WorkerParameters::isolatedCopy const):
+ (WebCore::WorkerThread::WorkerThread):
+ (WebCore::WorkerThread::createThread):
+ (WebCore::WorkerThread::evaluateScriptIfNecessary):
+ * workers/WorkerThread.h:
+ * workers/WorkerThreadMode.h: Added.
+ * workers/service/ServiceWorkerGlobalScope.cpp:
+ (WebCore::ServiceWorkerGlobalScope::updateExtendedEventsSet):
+ * workers/service/context/ServiceWorkerThread.cpp:
+ (WebCore::generateWorkerParameters):
+ (WebCore::ServiceWorkerThread::ServiceWorkerThread):
+ (WebCore::ServiceWorkerThread::finishedEvaluatingScript):
+ (WebCore::ServiceWorkerThread::startHeartBeatTimer):
+ * workers/service/context/ServiceWorkerThread.h:
+ * workers/service/context/ServiceWorkerThreadProxy.cpp:
+ (WebCore::ServiceWorkerThreadProxy::ServiceWorkerThreadProxy):
+ * workers/service/context/ServiceWorkerThreadProxy.h:
+ * workers/service/server/SWServer.cpp:
+ (WebCore::SWServer::SWServer):
+ (WebCore::SWServer::installContextData):
+ (WebCore::SWServer::runServiceWorker):
+ * workers/service/server/SWServer.h:
+ * workers/service/server/SWServerToContextConnection.h:
+
2021-09-29 Basuke Suzuki <[email protected]>
Suppress warnings for implicit copy assignment operator/copy constructor with clang 13
Modified: trunk/Source/WebCore/Headers.cmake (283294 => 283295)
--- trunk/Source/WebCore/Headers.cmake 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/Headers.cmake 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1731,6 +1731,7 @@
workers/WorkerScriptLoader.h
workers/WorkerScriptLoaderClient.h
workers/WorkerThread.h
+ workers/WorkerThreadMode.h
workers/WorkerThreadType.h
workers/WorkerType.h
Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp (283294 => 283295)
--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -609,8 +609,6 @@
void IDBConnectionProxy::forgetActivityForCurrentThread()
{
- ASSERT(!isMainThread());
-
{
Locker locker { m_databaseConnectionMapLock };
removeItemsMatchingCurrentThread(m_databaseConnectionMap);
Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (283294 => 283295)
--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -592,10 +592,10 @@
if (!m_workerGlobalScope)
return;
WorkerRunLoop& runLoop = m_workerGlobalScope->thread().runLoop();
- MessageQueueWaitResult result = MessageQueueMessageReceived;
+ bool success = true;
ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.ptr();
- while (m_workerGlobalScope && clientWrapper && !clientWrapper->syncMethodDone() && result != MessageQueueTerminated) {
- result = runLoop.runInMode(m_workerGlobalScope.get(), m_taskMode); // May cause this bridge to get disconnected, which makes m_workerGlobalScope become null.
+ while (m_workerGlobalScope && clientWrapper && !clientWrapper->syncMethodDone() && success) {
+ success = runLoop.runInMode(m_workerGlobalScope.get(), m_taskMode); // May cause this bridge to get disconnected, which makes m_workerGlobalScope become null.
clientWrapper = m_workerClientWrapper.ptr();
}
}
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (283294 => 283295)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1313,6 +1313,7 @@
462E4C502616A811003A2C67 /* ScriptBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 462E4C4D2616A801003A2C67 /* ScriptBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
463521AD2081092A00C28922 /* WindowProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 463521AA2081090B00C28922 /* WindowProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
463EB6231B8789E00096ED51 /* TagCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 463EB6211B8789CB0096ED51 /* TagCollection.h */; };
+ 4650AD1926FCCA650047F7AD /* WorkerThreadMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
465307D01DB6EE4800E4137C /* JSUIEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E045EF1DAA104F00B0D8B9 /* JSUIEventInit.h */; };
46658DC91FA24B8700F7DD54 /* SWContextManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4672413B1FA24B140088BD6D /* SWContextManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
466C2DAD26C73AFC00651931 /* PolicyContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 466C2DAB26C73AFB00651931 /* PolicyContainer.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -8452,6 +8453,7 @@
463EB6201B8789CB0096ED51 /* TagCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagCollection.cpp; sourceTree = "<group>"; };
463EB6211B8789CB0096ED51 /* TagCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagCollection.h; sourceTree = "<group>"; };
4642404520EAF0ED00B29FD2 /* DatabaseManagerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseManagerCocoa.mm; sourceTree = "<group>"; };
+ 4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerThreadMode.h; sourceTree = "<group>"; };
465A8E781C8A24CE00E7D3E4 /* RuntimeApplicationChecksCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RuntimeApplicationChecksCocoa.mm; sourceTree = "<group>"; };
465EDD9F222F4EC300B46E16 /* DeviceOrientationOrMotionPermissionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceOrientationOrMotionPermissionState.h; sourceTree = "<group>"; };
465EDDA0222F4EC400B46E16 /* DeviceOrientationOrMotionPermissionState.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DeviceOrientationOrMotionPermissionState.idl; sourceTree = "<group>"; };
@@ -19504,6 +19506,7 @@
2EA768030FE7126400AB9C8A /* WorkerScriptLoaderClient.h */,
2E4346420F546A8200B0F1BA /* WorkerThread.cpp */,
2E4346430F546A8200B0F1BA /* WorkerThread.h */,
+ 4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */,
E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */,
51F174FC1F35898800C74950 /* WorkerType.h */,
51F174FA1F3588D700C74950 /* WorkerType.idl */,
@@ -35975,6 +35978,7 @@
2E4346550F546A8200B0F1BA /* WorkerThread.h in Headers */,
0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */,
97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */,
+ 4650AD1926FCCA650047F7AD /* WorkerThreadMode.h in Headers */,
E3AFD7AD255F50EB00E5E30E /* WorkerThreadType.h in Headers */,
A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */,
51F174FE1F35899200C74950 /* WorkerType.h in Headers */,
Modified: trunk/Source/WebCore/inspector/WorkerDebugger.cpp (283294 => 283295)
--- trunk/Source/WebCore/inspector/WorkerDebugger.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/inspector/WorkerDebugger.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -79,9 +79,13 @@
TimerBase::fireTimersInNestedEventLoop();
+ // FIXME: Add support for pausing workers running on the main thread.
+ if (!is<WorkerDedicatedRunLoop>(m_globalScope.workerOrWorkletThread()->runLoop()))
+ return;
+
MessageQueueWaitResult result;
do {
- result = m_globalScope.workerOrWorkletThread()->runLoop().runInDebuggerMode(m_globalScope);
+ result = downcast<WorkerDedicatedRunLoop>(m_globalScope.workerOrWorkletThread()->runLoop()).runInDebuggerMode(m_globalScope);
} while (result != MessageQueueTerminated && !doneProcessingDebuggerEvents());
}
Modified: trunk/Source/WebCore/loader/WorkerThreadableLoader.cpp (283294 => 283295)
--- trunk/Source/WebCore/loader/WorkerThreadableLoader.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/loader/WorkerThreadableLoader.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -74,11 +74,11 @@
auto mode = makeString("loadResourceSynchronouslyMode", runLoop.createUniqueId());
auto loader = WorkerThreadableLoader::create(workerOrWorkletGlobalScope, client, mode, WTFMove(request), options, String());
- MessageQueueWaitResult result = MessageQueueMessageReceived;
- while (!loader->done() && result != MessageQueueTerminated)
- result = runLoop.runInMode(&workerOrWorkletGlobalScope, mode);
+ bool success = true;
+ while (!loader->done() && success)
+ success = runLoop.runInMode(&workerOrWorkletGlobalScope, mode);
- if (!loader->done() && result == MessageQueueTerminated)
+ if (!loader->done() && !success)
loader->cancel();
}
Modified: trunk/Source/WebCore/page/PerformanceUserTiming.cpp (283294 => 283295)
--- trunk/Source/WebCore/page/PerformanceUserTiming.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/page/PerformanceUserTiming.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -137,7 +137,7 @@
ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(const String& mark) const
{
- if (!is<Document>(m_performance.scriptExecutionContext())) {
+ if (!isMainThread()) {
if (isRestrictedMarkNameNonMainThread(mark))
return Exception { TypeError };
} else {
Modified: trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -45,6 +45,9 @@
public:
virtual ~WorkerOrWorkletGlobalScope();
+ using ScriptExecutionContext::weakPtrFactory;
+ using WeakValueType = ScriptExecutionContext::WeakValueType;
+
bool isClosing() const { return m_isClosing; }
WorkerOrWorkletThread* workerOrWorkletThread() const { return m_thread; }
Modified: trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -267,10 +267,10 @@
return moduleRecord.evaluate(&globalObject, awaitedValue, resumeMode);
}
-MessageQueueWaitResult WorkerOrWorkletScriptController::loadModuleSynchronously(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode)
+bool WorkerOrWorkletScriptController::loadModuleSynchronously(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode)
{
if (isExecutionForbidden())
- return MessageQueueTerminated;
+ return false;
initScriptIfNeeded();
@@ -340,14 +340,14 @@
// task is queued in WorkerRunLoop before start running module scripts. This task should not be discarded
// in the following driving of the RunLoop which mainly attempt to collect initial load of module scripts.
String taskMode = WorkerModuleScriptLoader::taskMode();
- MessageQueueWaitResult result = MessageQueueMessageReceived;
- while ((!protector->isLoaded() && !protector->wasCanceled()) && result != MessageQueueTerminated) {
- result = runLoop.runInMode(m_globalScope, taskMode);
- if (result != MessageQueueTerminated)
+ bool success = true;
+ while ((!protector->isLoaded() && !protector->wasCanceled()) && success) {
+ success = runLoop.runInMode(m_globalScope, taskMode);
+ if (success)
m_globalScope->eventLoop().performMicrotaskCheckpoint();
}
- return result;
+ return success;
}
void WorkerOrWorkletScriptController::linkAndEvaluateModule(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode, String* returnedExceptionMessage)
Modified: trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -99,7 +99,7 @@
JSC::JSValue evaluateModule(JSC::JSModuleRecord&, JSC::JSValue awaitedValue, JSC::JSValue resumeMode);
void linkAndEvaluateModule(WorkerScriptFetcher&, const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
- MessageQueueWaitResult loadModuleSynchronously(WorkerScriptFetcher&, const ScriptSourceCode&);
+ bool loadModuleSynchronously(WorkerScriptFetcher&, const ScriptSourceCode&);
void loadAndEvaluateModule(const URL& moduleURL, FetchOptions::Credentials, CompletionHandler<void(std::optional<Exception>&&)>&&);
Modified: trunk/Source/WebCore/workers/WorkerOrWorkletThread.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerOrWorkletThread.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletThread.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -27,6 +27,7 @@
#include "WorkerOrWorkletThread.h"
#include "ThreadGlobalData.h"
+#include "WorkerEventLoop.h"
#include "WorkerOrWorkletGlobalScope.h"
#include "WorkerOrWorkletScriptController.h"
@@ -54,8 +55,20 @@
return workerOrWorkletThreads;
}
-WorkerOrWorkletThread::WorkerOrWorkletThread(const String& identifier)
+static UniqueRef<WorkerRunLoop> constructRunLoop(WorkerThreadMode workerThreadMode)
+{
+ switch (workerThreadMode) {
+ case WorkerThreadMode::UseMainThread:
+ return makeUniqueRef<WorkerMainRunLoop>();
+ case WorkerThreadMode::CreateNewThread:
+ break;
+ }
+ return makeUniqueRef<WorkerDedicatedRunLoop>();
+}
+
+WorkerOrWorkletThread::WorkerOrWorkletThread(const String& identifier, WorkerThreadMode workerThreadMode)
: m_identifier(identifier)
+ , m_runLoop(constructRunLoop(workerThreadMode))
{
Locker locker { workerOrWorkletThreadsLock() };
workerOrWorkletThreads().add(this);
@@ -73,9 +86,13 @@
ASSERT(!m_pausedForDebugger);
m_pausedForDebugger = true;
+ // FIXME: Add support for debugging workers running on the main thread.
+ if (!is<WorkerDedicatedRunLoop>(m_runLoop.get()))
+ return;
+
MessageQueueWaitResult result;
do {
- result = m_runLoop.runInDebuggerMode(*m_globalScope);
+ result = downcast<WorkerDedicatedRunLoop>(m_runLoop.get()).runInDebuggerMode(*m_globalScope);
} while (result != MessageQueueTerminated && m_pausedForDebugger);
}
@@ -87,7 +104,8 @@
void WorkerOrWorkletThread::runEventLoop()
{
// Does not return until terminated.
- m_runLoop.run(m_globalScope.get());
+ if (is<WorkerDedicatedRunLoop>(m_runLoop.get()))
+ downcast<WorkerDedicatedRunLoop>(m_runLoop.get()).run(m_globalScope.get());
}
void WorkerOrWorkletThread::workerOrWorkletThread()
@@ -94,6 +112,23 @@
{
Ref protectedThis { *this };
+ if (isMainThread()) {
+ m_globalScope = createGlobalScope();
+ if (!m_globalScope)
+ return;
+
+ downcast<WorkerMainRunLoop>(m_runLoop.get()).setGlobalScope(*m_globalScope);
+
+ String exceptionMessage;
+ evaluateScriptIfNecessary(exceptionMessage);
+
+ callOnMainThread([evaluateCallback = WTFMove(m_evaluateCallback), message = WTFMove(exceptionMessage)] {
+ if (evaluateCallback)
+ evaluateCallback(message);
+ });
+ return;
+ }
+
// Propagate the mainThread's fenv to workers.
#if PLATFORM(IOS_FAMILY)
FloatingPointEnvironment::singleton().propagateMainThreadEnvironment();
@@ -120,7 +155,7 @@
scriptController = m_globalScope->script();
- if (m_runLoop.terminated()) {
+ if (m_runLoop->terminated()) {
// The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
// forbidExecution() couldn't be called from stop().
scriptController->scheduleExecutionTermination();
@@ -132,7 +167,7 @@
startRunningDebuggerTasks();
// If the worker was somehow terminated while processing debugger commands.
- if (m_runLoop.terminated())
+ if (m_runLoop->terminated())
scriptController->forbidExecution();
}
@@ -228,7 +263,18 @@
if (globalScope()) {
globalScope()->script()->scheduleExecutionTermination();
- m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
+ if (is<WorkerMainRunLoop>(m_runLoop.get())) {
+ auto globalScope = std::exchange(m_globalScope, nullptr);
+ globalScope->prepareForDestruction();
+ globalScope->clearScript();
+ m_runLoop->terminate();
+
+ if (m_stoppedCallback)
+ callOnMainThread(std::exchange(m_stoppedCallback, nullptr));
+ return;
+ }
+
+ m_runLoop->postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
auto& globalScope = downcast<WorkerOrWorkletGlobalScope>(context);
globalScope.prepareForDestruction();
@@ -244,13 +290,16 @@
} });
return;
}
- m_runLoop.terminate();
+ m_runLoop->terminate();
}
void WorkerOrWorkletThread::suspend()
{
m_isSuspended = true;
- m_runLoop.postTask([&](ScriptExecutionContext&) {
+ if (is<WorkerMainRunLoop>(m_runLoop.get()))
+ return;
+
+ m_runLoop->postTask([&](ScriptExecutionContext&) {
if (globalScope())
globalScope()->suspend();
@@ -265,6 +314,9 @@
{
ASSERT(m_isSuspended);
m_isSuspended = false;
+ if (is<WorkerMainRunLoop>(m_runLoop.get()))
+ return;
+
m_suspensionSemaphore.signal();
}
Modified: trunk/Source/WebCore/workers/WorkerOrWorkletThread.h (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerOrWorkletThread.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletThread.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -26,6 +26,7 @@
#pragma once
#include "WorkerRunLoop.h"
+#include "WorkerThreadMode.h"
#include <wtf/Forward.h>
#include <wtf/Function.h>
#include <wtf/Lock.h>
@@ -40,7 +41,6 @@
class WorkerDebuggerProxy;
class WorkerLoaderProxy;
-class WorkerRunLoop;
class WorkerOrWorkletThread : public ThreadSafeRefCounted<WorkerOrWorkletThread> {
public:
@@ -70,7 +70,7 @@
static void releaseFastMallocFreeMemoryInAllThreads();
protected:
- explicit WorkerOrWorkletThread(const String& identifier);
+ explicit WorkerOrWorkletThread(const String& identifier, WorkerThreadMode = WorkerThreadMode::CreateNewThread);
void workerOrWorkletThread();
// Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
@@ -88,7 +88,7 @@
Lock m_threadCreationAndGlobalScopeLock;
RefPtr<WorkerOrWorkletGlobalScope> m_globalScope;
RefPtr<WTF::Thread> m_thread;
- WorkerRunLoop m_runLoop;
+ UniqueRef<WorkerRunLoop> m_runLoop;
Function<void(const String&)> m_evaluateCallback;
Function<void()> m_stoppedCallback;
BinarySemaphore m_suspensionSemaphore;
Modified: trunk/Source/WebCore/workers/WorkerRunLoop.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerRunLoop.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerRunLoop.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -76,7 +76,7 @@
return m_defaultMode;
}
- bool operator()(const WorkerRunLoop::Task& task) const
+ bool operator()(const WorkerDedicatedRunLoop::Task& task) const
{
return m_defaultMode || m_mode == task.mode();
}
@@ -86,12 +86,12 @@
bool m_defaultMode;
};
-WorkerRunLoop::WorkerRunLoop()
+WorkerDedicatedRunLoop::WorkerDedicatedRunLoop()
: m_sharedTimer(makeUnique<WorkerSharedTimer>())
{
}
-WorkerRunLoop::~WorkerRunLoop()
+WorkerDedicatedRunLoop::~WorkerDedicatedRunLoop()
{
ASSERT(!m_nestedCount);
}
@@ -110,7 +110,7 @@
WTF_MAKE_NONCOPYABLE(RunLoopSetup);
public:
enum class IsForDebugging { No, Yes };
- RunLoopSetup(WorkerRunLoop& runLoop, IsForDebugging isForDebugging)
+ RunLoopSetup(WorkerDedicatedRunLoop& runLoop, IsForDebugging isForDebugging)
: m_runLoop(runLoop)
, m_isForDebugging(isForDebugging)
{
@@ -130,37 +130,36 @@
m_runLoop.m_debugCount--;
}
private:
- WorkerRunLoop& m_runLoop;
+ WorkerDedicatedRunLoop& m_runLoop;
IsForDebugging m_isForDebugging { IsForDebugging::No };
};
-void WorkerRunLoop::run(WorkerOrWorkletGlobalScope* context)
+void WorkerDedicatedRunLoop::run(WorkerOrWorkletGlobalScope* context)
{
RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No);
ModePredicate modePredicate(defaultMode());
MessageQueueWaitResult result;
do {
- result = runInMode(context, modePredicate, WaitForMessage);
+ result = runInMode(context, modePredicate);
} while (result != MessageQueueTerminated);
runCleanupTasks(context);
}
-MessageQueueWaitResult WorkerRunLoop::runInDebuggerMode(WorkerOrWorkletGlobalScope& context)
+MessageQueueWaitResult WorkerDedicatedRunLoop::runInDebuggerMode(WorkerOrWorkletGlobalScope& context)
{
RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::Yes);
- return runInMode(&context, ModePredicate { debuggerMode() }, WaitForMessage);
+ return runInMode(&context, ModePredicate { debuggerMode() });
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode, WaitMode waitMode)
+bool WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode)
{
ASSERT(mode != debuggerMode());
RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No);
ModePredicate modePredicate(String { mode });
- MessageQueueWaitResult result = runInMode(context, modePredicate, waitMode);
- return result;
+ return runInMode(context, modePredicate) != MessageQueueWaitResult::MessageQueueTerminated;
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode)
+MessageQueueWaitResult WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const ModePredicate& predicate)
{
ASSERT(context);
ASSERT(context->workerOrWorkletThread()->thread() == &Thread::current());
@@ -185,7 +184,7 @@
timeoutDelay = std::max(0_s, Seconds(timeUntilNextCFRunLoopTimerInSeconds));
#endif
- if (waitMode == WaitForMessage && predicate.isDefaultMode() && m_sharedTimer->isActive())
+ if (predicate.isDefaultMode() && m_sharedTimer->isActive())
timeoutDelay = std::min(timeoutDelay, m_sharedTimer->fireTimeDelay());
if (auto* script = context->script()) {
@@ -225,7 +224,7 @@
return result;
}
-void WorkerRunLoop::runCleanupTasks(WorkerOrWorkletGlobalScope* context)
+void WorkerDedicatedRunLoop::runCleanupTasks(WorkerOrWorkletGlobalScope* context)
{
ASSERT(context);
ASSERT(context->workerOrWorkletThread()->thread() == &Thread::current());
@@ -239,7 +238,7 @@
}
}
-void WorkerRunLoop::terminate()
+void WorkerDedicatedRunLoop::terminate()
{
m_messageQueue.kill();
}
@@ -249,12 +248,12 @@
postTaskForMode(WTFMove(task), defaultMode());
}
-void WorkerRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
+void WorkerDedicatedRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
{
m_messageQueue.appendAndKill(makeUnique<Task>(WTFMove(task), defaultMode()));
}
-void WorkerRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& mode)
+void WorkerDedicatedRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& mode)
{
m_messageQueue.append(makeUnique<Task>(WTFMove(task), mode));
}
@@ -264,16 +263,58 @@
postTaskForMode(WTFMove(task), debuggerMode());
}
-void WorkerRunLoop::Task::performTask(WorkerOrWorkletGlobalScope* context)
+void WorkerDedicatedRunLoop::Task::performTask(WorkerOrWorkletGlobalScope* context)
{
if ((!context->isClosing() && context->script() && !context->script()->isTerminatingExecution()) || m_task.isCleanupTask())
m_task.performTask(*context);
}
-WorkerRunLoop::Task::Task(ScriptExecutionContext::Task&& task, const String& mode)
+WorkerDedicatedRunLoop::Task::Task(ScriptExecutionContext::Task&& task, const String& mode)
: m_task(WTFMove(task))
, m_mode(mode.isolatedCopy())
{
}
+WorkerMainRunLoop::WorkerMainRunLoop()
+{
+}
+
+void WorkerMainRunLoop::setGlobalScope(WorkerOrWorkletGlobalScope& globalScope)
+{
+ m_workerOrWorkletGlobalScope = makeWeakPtr(globalScope);
+}
+
+void WorkerMainRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
+{
+ if (m_terminated)
+ return;
+
+ RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), task = WTFMove(task)]() mutable {
+ if (!weakThis || !weakThis->m_workerOrWorkletGlobalScope || weakThis->m_terminated)
+ return;
+
+ weakThis->m_terminated = true;
+ task.performTask(*weakThis->m_workerOrWorkletGlobalScope);
+ });
+}
+
+void WorkerMainRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& /*mode*/)
+{
+ if (m_terminated)
+ return;
+
+ RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), task = WTFMove(task)]() mutable {
+ if (!weakThis || !weakThis->m_workerOrWorkletGlobalScope || weakThis->m_terminated)
+ return;
+
+ task.performTask(*weakThis->m_workerOrWorkletGlobalScope);
+ });
+}
+
+bool WorkerMainRunLoop::runInMode(WorkerOrWorkletGlobalScope*, const String&)
+{
+ RunLoop::main().cycle();
+ return true;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/WorkerRunLoop.h (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerRunLoop.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerRunLoop.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -42,30 +42,49 @@
class WorkerSharedTimer;
class WorkerRunLoop {
+ WTF_MAKE_FAST_ALLOCATED;
public:
- WorkerRunLoop();
- ~WorkerRunLoop();
+ enum class Type : bool { WorkerDedicatedRunLoop, WorkerMainRunLoop };
+
+ virtual ~WorkerRunLoop() = default;
+
+ virtual bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode) = 0;
+ virtual void postTaskAndTerminate(ScriptExecutionContext::Task&&) = 0;
+ virtual void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) = 0;
+ virtual void terminate() = 0;
+ virtual bool terminated() const = 0;
+ virtual Type type() const = 0;
+
+ void postTask(ScriptExecutionContext::Task&&);
+ void postDebuggerTask(ScriptExecutionContext::Task&&);
+
+ WEBCORE_EXPORT static String defaultMode();
+
+ unsigned long createUniqueId() { return ++m_uniqueId; }
+
+private:
+ unsigned long m_uniqueId { 0 };
+};
+
+class WorkerDedicatedRunLoop final : public WorkerRunLoop {
+public:
+ WorkerDedicatedRunLoop();
+ ~WorkerDedicatedRunLoop();
// Blocking call. Waits for tasks and timers, invokes the callbacks.
void run(WorkerOrWorkletGlobalScope*);
- enum WaitMode { WaitForMessage, DontWaitForMessage };
-
// Waits for a single task and returns.
- MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const String& mode, WaitMode = WaitForMessage);
+ bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode) final;
MessageQueueWaitResult runInDebuggerMode(WorkerOrWorkletGlobalScope&);
- void terminate();
- bool terminated() const { return m_messageQueue.killed(); }
+ void terminate() final;
+ bool terminated() const final { return m_messageQueue.killed(); }
+ Type type() const final { return Type::WorkerDedicatedRunLoop; }
- void postTask(ScriptExecutionContext::Task&&);
- void postTaskAndTerminate(ScriptExecutionContext::Task&&);
- WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
- void postDebuggerTask(ScriptExecutionContext::Task&&);
+ void postTaskAndTerminate(ScriptExecutionContext::Task&&) final;
+ WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) final;
- unsigned long createUniqueId() { return ++m_uniqueId; }
-
- WEBCORE_EXPORT static String defaultMode();
class Task {
WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -78,12 +97,12 @@
ScriptExecutionContext::Task m_task;
String m_mode;
- friend class WorkerRunLoop;
+ friend class WorkerDedicatedRunLoop;
};
private:
friend class RunLoopSetup;
- MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const ModePredicate&, WaitMode);
+ MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const ModePredicate&);
// Runs any clean up tasks that are currently in the queue and returns.
// This should only be called when the context is closed or loop has been terminated.
@@ -95,7 +114,33 @@
std::unique_ptr<WorkerSharedTimer> m_sharedTimer;
int m_nestedCount { 0 };
int m_debugCount { 0 };
- unsigned long m_uniqueId { 0 };
};
+class WorkerMainRunLoop final : public WorkerRunLoop, public CanMakeWeakPtr<WorkerMainRunLoop> {
+public:
+ WorkerMainRunLoop();
+
+ void setGlobalScope(WorkerOrWorkletGlobalScope&);
+
+ void terminate() final { m_terminated = true; }
+ bool terminated() const final { return m_terminated; }
+
+ bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode);
+ void postTaskAndTerminate(ScriptExecutionContext::Task&&) final;
+ void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) final;
+ Type type() const final { return Type::WorkerMainRunLoop; }
+
+private:
+ WeakPtr<WorkerOrWorkletGlobalScope> m_workerOrWorkletGlobalScope;
+ bool m_terminated { false };
+};
+
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WorkerDedicatedRunLoop)
+ static bool isType(const WebCore::WorkerRunLoop& runLoop) { return runLoop.type() == WebCore::WorkerRunLoop::Type::WorkerDedicatedRunLoop; }
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WorkerMainRunLoop)
+ static bool isType(const WebCore::WorkerRunLoop& runLoop) { return runLoop.type() == WebCore::WorkerRunLoop::Type::WorkerMainRunLoop; }
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerThread.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -60,7 +60,8 @@
referrerPolicy,
workerType,
credentials,
- settingsValues.isolatedCopy()
+ settingsValues.isolatedCopy(),
+ workerThreadMode
};
}
@@ -86,7 +87,7 @@
}
WorkerThread::WorkerThread(const WorkerParameters& params, const ScriptBuffer& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerDebuggerProxy& workerDebuggerProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode startMode, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
- : WorkerOrWorkletThread(params.identifier.isolatedCopy())
+ : WorkerOrWorkletThread(params.identifier.isolatedCopy(), params.workerThreadMode)
, m_workerLoaderProxy(workerLoaderProxy)
, m_workerDebuggerProxy(workerDebuggerProxy)
, m_workerReportingProxy(workerReportingProxy)
@@ -106,6 +107,15 @@
Ref<Thread> WorkerThread::createThread()
{
+ if (is<WorkerMainRunLoop>(runLoop())) {
+ // This worker should run on the main thread.
+ RunLoop::main().dispatch([protectedThis = Ref { *this }] {
+ protectedThis->workerOrWorkletThread();
+ });
+ ASSERT(isMainThread());
+ return Thread::current();
+ }
+
return Thread::create(isServiceWorkerThread() ? "WebCore: Service Worker" : "WebCore: Worker", [this] {
workerOrWorkletThread();
}, ThreadType::_javascript_);
@@ -136,8 +146,8 @@
auto scriptFetcher = WorkerScriptFetcher::create(globalScope()->credentials(), globalScope()->destination(), globalScope()->referrerPolicy());
ScriptSourceCode sourceCode(m_startupData->sourceCode, URL(m_startupData->params.scriptURL), { }, JSC::SourceProviderSourceType::Module, scriptFetcher.copyRef());
sourceProvider = makeWeakPtr(static_cast<ScriptBufferSourceProvider&>(sourceCode.provider()));
- MessageQueueWaitResult result = globalScope()->script()->loadModuleSynchronously(scriptFetcher.get(), sourceCode);
- if (result != MessageQueueTerminated) {
+ bool success = globalScope()->script()->loadModuleSynchronously(scriptFetcher.get(), sourceCode);
+ if (success) {
if (std::optional<LoadableScript::Error> error = scriptFetcher->error()) {
if (std::optional<LoadableScript::ConsoleMessage> message = error->consoleMessage)
exceptionMessage = message->message;
Modified: trunk/Source/WebCore/workers/WorkerThread.h (283294 => 283295)
--- trunk/Source/WebCore/workers/WorkerThread.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/WorkerThread.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -72,6 +72,7 @@
WorkerType workerType;
FetchRequestCredentials credentials;
Settings::Values settingsValues;
+ WorkerThreadMode workerThreadMode { WorkerThreadMode::CreateNewThread };
WorkerParameters isolatedCopy() const;
};
Added: trunk/Source/WebCore/workers/WorkerThreadMode.h (0 => 283295)
--- trunk/Source/WebCore/workers/WorkerThreadMode.h (rev 0)
+++ trunk/Source/WebCore/workers/WorkerThreadMode.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+enum class WorkerThreadMode : bool { UseMainThread, CreateNewThread };
+
+}
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -114,7 +114,7 @@
// https://w3c.github.io/ServiceWorker/#update-service-worker-extended-events-set-algorithm
void ServiceWorkerGlobalScope::updateExtendedEventsSet(ExtendableEvent* newEvent)
{
- ASSERT(!isMainThread());
+ ASSERT(isContextThread());
ASSERT(!newEvent || !newEvent->isBeingDispatched());
bool hadPendingEvents = hasPendingEvents();
m_extendedEvents.removeAllMatching([](auto& event) {
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -73,8 +73,28 @@
// FIXME: Use a valid WorkerObjectProxy
// FIXME: Use valid runtime flags
-ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
- : WorkerThread({ contextData.scriptURL, emptyString(), "serviceworker:" + Inspector::IdentifiersFactory::createIdentifier(), WTFMove(userAgent), platformStrategies()->loaderStrategy()->isOnLine(), contextData.contentSecurityPolicy, false, contextData.crossOriginEmbedderPolicy, MonotonicTime::now(), { }, contextData.workerType, FetchRequestCredentials::Omit, settingsValues }, contextData.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), WorkerThreadStartMode::Normal, contextData.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled())
+static WorkerParameters generateWorkerParameters(const ServiceWorkerContextData& contextData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues)
+{
+ return {
+ contextData.scriptURL,
+ emptyString(),
+ "serviceworker:" + Inspector::IdentifiersFactory::createIdentifier(),
+ WTFMove(userAgent),
+ platformStrategies()->loaderStrategy()->isOnLine(),
+ contextData.contentSecurityPolicy,
+ false,
+ contextData.crossOriginEmbedderPolicy,
+ MonotonicTime::now(),
+ { },
+ contextData.workerType,
+ FetchRequestCredentials::Omit,
+ settingsValues,
+ workerThreadMode
+ };
+}
+
+ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
+ : WorkerThread(generateWorkerParameters(contextData, WTFMove(userAgent), workerThreadMode, settingsValues), contextData.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), WorkerThreadStartMode::Normal, contextData.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled())
, m_serviceWorkerIdentifier(contextData.serviceWorkerIdentifier)
, m_jobDataIdentifier(contextData.jobDataIdentifier)
, m_contextData(crossThreadCopy(WTFMove(contextData)))
@@ -194,7 +214,7 @@
void ServiceWorkerThread::finishedEvaluatingScript()
{
- ASSERT(!isMainThread());
+ ASSERT(globalScope()->isContextThread());
m_doesHandleFetch = globalScope()->hasEventListeners(eventNames().fetchEvent);
}
@@ -226,6 +246,10 @@
void ServiceWorkerThread::startHeartBeatTimer()
{
+ // We cannot detect responsiveness for service workers running on the main thread by using a main thread timer.
+ if (is<WorkerMainRunLoop>(runLoop()))
+ return;
+
if (m_heartBeatTimer.isActive())
return;
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h (283294 => 283295)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -79,7 +79,7 @@
void runEventLoop() override;
private:
- WEBCORE_EXPORT ServiceWorkerThread(ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, const Settings::Values&, WorkerLoaderProxy&, WorkerDebuggerProxy&, IDBClient::IDBConnectionProxy*, SocketProvider*);
+ WEBCORE_EXPORT ServiceWorkerThread(ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, WorkerThreadMode, const Settings::Values&, WorkerLoaderProxy&, WorkerDebuggerProxy&, IDBClient::IDBConnectionProxy*, SocketProvider*);
bool isServiceWorkerThread() const final { return true; }
void finishedEvaluatingScript() final;
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -93,13 +93,13 @@
return set;
}
-ServiceWorkerThreadProxy::ServiceWorkerThreadProxy(PageConfiguration&& pageConfiguration, ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, CacheStorageProvider& cacheStorageProvider, StorageBlockingPolicy storageBlockingPolicy)
+ServiceWorkerThreadProxy::ServiceWorkerThreadProxy(PageConfiguration&& pageConfiguration, ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, CacheStorageProvider& cacheStorageProvider, StorageBlockingPolicy storageBlockingPolicy)
: m_page(createPageForServiceWorker(WTFMove(pageConfiguration), contextData, storageBlockingPolicy))
, m_document(*m_page->mainFrame().document())
#if ENABLE(REMOTE_INSPECTOR)
, m_remoteDebuggable(makeUnique<ServiceWorkerDebuggable>(*this, contextData))
#endif
- , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), m_document->settingsValues(), *this, *this, idbConnectionProxy(m_document), m_document->socketProvider()))
+ , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), workerThreadMode, m_document->settingsValues(), *this, *this, idbConnectionProxy(m_document), m_document->socketProvider()))
, m_cacheStorageProvider(cacheStorageProvider)
, m_inspectorProxy(*this)
{
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (283294 => 283295)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -49,6 +49,7 @@
class PageConfiguration;
class ServiceWorkerInspectorProxy;
struct ServiceWorkerContextData;
+enum class WorkerThreadMode : bool;
class ServiceWorkerThreadProxy final : public ThreadSafeRefCounted<ServiceWorkerThreadProxy>, public WorkerLoaderProxy, public WorkerDebuggerProxy {
public:
@@ -85,7 +86,7 @@
WEBCORE_EXPORT bool lastNavigationWasAppInitiated();
private:
- WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, CacheStorageProvider&, StorageBlockingPolicy);
+ WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, WorkerThreadMode, CacheStorageProvider&, StorageBlockingPolicy);
WEBCORE_EXPORT static void networkStateChanged(bool isOnLine);
Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (283294 => 283295)
--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -327,7 +327,7 @@
m_server.removeClientServiceWorkerRegistration(*this, identifier);
}
-SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool hasServiceWorkerEntitlement, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
+SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
: m_originStore(WTFMove(originStore))
, m_sessionID(sessionID)
, m_isProcessTerminationDelayEnabled(processTerminationDelayEnabled)
@@ -334,6 +334,7 @@
, m_createContextConnectionCallback(WTFMove(callback))
, m_softUpdateCallback(WTFMove(softUpdateCallback))
, m_appBoundDomainsCallback(WTFMove(appBoundDomainsCallback))
+ , m_shouldRunServiceWorkersOnMainThreadForTesting(shouldRunServiceWorkersOnMainThreadForTesting)
, m_hasServiceWorkerEntitlement(hasServiceWorkerEntitlement)
{
RELEASE_LOG_IF(registrationDatabaseDirectory.isEmpty(), ServiceWorker, "No path to store the service worker registrations");
@@ -726,7 +727,8 @@
auto result = m_runningOrTerminatingWorkers.add(data.serviceWorkerIdentifier, worker.copyRef());
ASSERT_UNUSED(result, result.isNewEntry);
- connection->installServiceWorkerContext(data, worker->data(), userAgent);
+ auto workerThreadMode = m_shouldRunServiceWorkersOnMainThreadForTesting ? WorkerThreadMode::UseMainThread : WorkerThreadMode::CreateNewThread;
+ connection->installServiceWorkerContext(data, worker->data(), userAgent, workerThreadMode);
}
void SWServer::runServiceWorkerIfNecessary(ServiceWorkerIdentifier identifier, RunServiceWorkerCallback&& callback)
@@ -794,7 +796,8 @@
auto* contextConnection = worker->contextConnection();
ASSERT(contextConnection);
- contextConnection->installServiceWorkerContext(worker->contextData(), worker->data(), worker->userAgent());
+ auto workerThreadMode = m_shouldRunServiceWorkersOnMainThreadForTesting ? WorkerThreadMode::UseMainThread : WorkerThreadMode::CreateNewThread;
+ contextConnection->installServiceWorkerContext(worker->contextData(), worker->data(), worker->userAgent(), workerThreadMode);
return true;
}
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (283294 => 283295)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -38,6 +38,7 @@
#include "ServiceWorkerRegistrationData.h"
#include "ServiceWorkerRegistrationKey.h"
#include "ServiceWorkerTypes.h"
+#include "WorkerThreadMode.h"
#include <pal/SessionID.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -128,7 +129,7 @@
using SoftUpdateCallback = Function<void(ServiceWorkerJobData&& jobData, bool shouldRefreshCache, ResourceRequest&&, CompletionHandler<void(const ServiceWorkerFetchResult&)>&&)>;
using CreateContextConnectionCallback = Function<void(const WebCore::RegistrableDomain&, CompletionHandler<void()>&&)>;
using AppBoundDomainsCallback = Function<void(CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&)>;
- WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool hasServiceWorkerEntitlement, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
+ WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
WEBCORE_EXPORT ~SWServer();
@@ -281,6 +282,7 @@
AppBoundDomainsCallback m_appBoundDomainsCallback;
HashSet<WebCore::RegistrableDomain> m_appBoundDomains;
+ bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
bool m_hasServiceWorkerEntitlement { false };
bool m_hasReceivedAppBoundDomains { false };
unsigned m_uniqueRegistrationCount { 0 };
Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (283294 => 283295)
--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -42,6 +42,7 @@
struct ServiceWorkerClientIdentifier;
struct ServiceWorkerContextData;
struct ServiceWorkerJobDataIdentifier;
+enum class WorkerThreadMode : bool;
class SWServerToContextConnection {
WTF_MAKE_FAST_ALLOCATED;
@@ -51,7 +52,7 @@
SWServerToContextConnectionIdentifier identifier() const { return m_identifier; }
// Messages to the SW host process
- virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const ServiceWorkerData&, const String& userAgent) = 0;
+ virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const ServiceWorkerData&, const String& userAgent, WorkerThreadMode) = 0;
virtual void updateAppInitiatedValue(ServiceWorkerIdentifier, LastNavigationWasAppInitiated) = 0;
virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
Modified: trunk/Source/WebKit/ChangeLog (283294 => 283295)
--- trunk/Source/WebKit/ChangeLog 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/ChangeLog 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1,3 +1,41 @@
+2021-09-29 Chris Dumez <[email protected]>
+
+ Add support for running service workers on the main thread
+ https://bugs.webkit.org/show_bug.cgi?id=230649
+
+ Reviewed by Alex Christensen.
+
+ Add support for running service workers on the main thread (off by default).
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::swServerForSession):
+ * NetworkProcess/NetworkSession.cpp:
+ (WebKit::NetworkSession::NetworkSession):
+ * NetworkProcess/NetworkSession.h:
+ (WebKit::NetworkSession::shouldRunServiceWorkersOnMainThread const):
+ * NetworkProcess/NetworkSessionCreationParameters.cpp:
+ (WebKit::NetworkSessionCreationParameters::encode const):
+ (WebKit::NetworkSessionCreationParameters::decode):
+ * NetworkProcess/NetworkSessionCreationParameters.h:
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+ (WebKit::WebSWServerToContextConnection::installServiceWorkerContext):
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+ * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
+ * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
+ (-[_WKWebsiteDataStoreConfiguration shouldRunServiceWorkersOnMainThread]):
+ (-[_WKWebsiteDataStoreConfiguration setShouldRunServiceWorkersOnMainThread:]):
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::parameters):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
+ (WebKit::WebsiteDataStoreConfiguration::copy const):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
+ (WebKit::WebsiteDataStoreConfiguration::shouldRunServiceWorkersOnMainThread const):
+ (WebKit::WebsiteDataStoreConfiguration::setShouldRunServiceWorkersOnMainThread):
+ * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+ (WebKit::WebSWContextManagerConnection::installServiceWorker):
+ * WebProcess/Storage/WebSWContextManagerConnection.h:
+ * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
2021-09-29 Alex Christensen <[email protected]>
Add weakThis check in addition to null check added in r282881
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -2486,7 +2486,10 @@
completionHandler({ });
};
#endif
- return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, parentProcessHasServiceWorkerEntitlement(), [this, sessionID](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
+ bool shouldRunServiceWorkersOnMainThreadForTesting = false;
+ if (auto* session = networkSession(sessionID))
+ shouldRunServiceWorkersOnMainThreadForTesting = session->shouldRunServiceWorkersOnMainThreadForTesting();
+ return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, shouldRunServiceWorkersOnMainThreadForTesting, parentProcessHasServiceWorkerEntitlement(), [this, sessionID](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
ServiceWorkerSoftUpdateLoader::start(networkSession(sessionID), WTFMove(jobData), shouldRefreshCache, WTFMove(request), WTFMove(completionHandler));
}, [this, sessionID](auto& registrableDomain, auto&& completionHandler) {
ASSERT(!registrableDomain.isEmpty());
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -118,6 +118,7 @@
, m_broadcastChannelRegistry(makeUniqueRef<NetworkBroadcastChannelRegistry>())
, m_testSpeedMultiplier(parameters.testSpeedMultiplier)
, m_allowsServerPreconnect(parameters.allowsServerPreconnect)
+ , m_shouldRunServiceWorkersOnMainThreadForTesting(parameters.shouldRunServiceWorkersOnMainThreadForTesting)
{
if (!m_sessionID.isEphemeral()) {
String networkCacheDirectory = parameters.networkCacheDirectory;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -163,6 +163,7 @@
unsigned testSpeedMultiplier() const { return m_testSpeedMultiplier; }
bool allowsServerPreconnect() const { return m_allowsServerPreconnect; }
+ bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
@@ -239,6 +240,7 @@
UniqueRef<NetworkBroadcastChannelRegistry> m_broadcastChannelRegistry;
unsigned m_testSpeedMultiplier { 1 };
bool m_allowsServerPreconnect { true };
+ bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
#if ENABLE(SERVICE_WORKER)
HashSet<std::unique_ptr<ServiceWorkerSoftUpdateLoader>> m_softUpdateLoaders;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -83,6 +83,7 @@
encoder << suppressesConnectionTerminationOnSystemChange;
encoder << allowsServerPreconnect;
encoder << requiresSecureHTTPSProxyConnection;
+ encoder << shouldRunServiceWorkersOnMainThreadForTesting;
encoder << preventsSystemHTTPProxyAuthentication;
encoder << appHasRequestedCrossWebsiteTrackingPermission;
encoder << useNetworkLoader;
@@ -274,6 +275,11 @@
decoder >> requiresSecureHTTPSProxyConnection;
if (!requiresSecureHTTPSProxyConnection)
return std::nullopt;
+
+ std::optional<bool> shouldRunServiceWorkersOnMainThreadForTesting;
+ decoder >> shouldRunServiceWorkersOnMainThreadForTesting;
+ if (!shouldRunServiceWorkersOnMainThreadForTesting)
+ return std::nullopt;
std::optional<bool> preventsSystemHTTPProxyAuthentication;
decoder >> preventsSystemHTTPProxyAuthentication;
@@ -349,6 +355,7 @@
, WTFMove(*suppressesConnectionTerminationOnSystemChange)
, WTFMove(*allowsServerPreconnect)
, WTFMove(*requiresSecureHTTPSProxyConnection)
+ , *shouldRunServiceWorkersOnMainThreadForTesting
, WTFMove(*preventsSystemHTTPProxyAuthentication)
, WTFMove(*appHasRequestedCrossWebsiteTrackingPermission)
, WTFMove(*useNetworkLoader)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -98,6 +98,7 @@
bool suppressesConnectionTerminationOnSystemChange { false };
bool allowsServerPreconnect { true };
bool requiresSecureHTTPSProxyConnection { false };
+ bool shouldRunServiceWorkersOnMainThreadForTesting { false };
bool preventsSystemHTTPProxyAuthentication { false };
bool appHasRequestedCrossWebsiteTrackingPermission { false };
bool useNetworkLoader { false };
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -87,9 +87,9 @@
connection->postMessageToServiceWorkerClient(destinationIdentifier.contextIdentifier, message, sourceIdentifier, sourceOrigin);
}
-void WebSWServerToContextConnection::installServiceWorkerContext(const ServiceWorkerContextData& contextData, const ServiceWorkerData& workerData, const String& userAgent)
+void WebSWServerToContextConnection::installServiceWorkerContext(const ServiceWorkerContextData& contextData, const ServiceWorkerData& workerData, const String& userAgent, WorkerThreadMode workerThreadMode)
{
- send(Messages::WebSWContextManagerConnection::InstallServiceWorker { contextData, workerData, userAgent });
+ send(Messages::WebSWContextManagerConnection::InstallServiceWorker { contextData, workerData, userAgent, workerThreadMode });
}
void WebSWServerToContextConnection::updateAppInitiatedValue(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::LastNavigationWasAppInitiated lastNavigationWasAppInitiated)
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (283294 => 283295)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -85,7 +85,7 @@
void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, const WebCore::MessageWithMessagePorts&, WebCore::ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin);
// Messages to the SW host WebProcess
- void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const WebCore::ServiceWorkerData&, const String& userAgent) final;
+ void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const WebCore::ServiceWorkerData&, const String& userAgent, WebCore::WorkerThreadMode) final;
void updateAppInitiatedValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppInitiated) final;
void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h (283294 => 283295)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -52,6 +52,7 @@
@property (nonatomic, nullable, copy) NSString *dataConnectionServiceType WK_API_AVAILABLE(macos(10.15.4), ios(13.4));
@property (nonatomic) BOOL preventsSystemHTTPProxyAuthentication WK_API_AVAILABLE(macos(11.0), ios(14.0));
@property (nonatomic) BOOL requiresSecureHTTPSProxyConnection WK_API_AVAILABLE(macos(11.0), ios(14.0));
+@property (nonatomic) BOOL shouldRunServiceWorkersOnMainThreadForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
// These properties only make sense for persistent data stores, and will throw
// an exception if set for non-persistent stores.
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm (283294 => 283295)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm 2021-09-30 02:19:59 UTC (rev 283295)
@@ -486,6 +486,16 @@
_configuration->setRequiresSecureHTTPSProxyConnection(requires);
}
+- (BOOL)shouldRunServiceWorkersOnMainThreadForTesting
+{
+ return _configuration->shouldRunServiceWorkersOnMainThreadForTesting();
+}
+
+- (void)setShouldRunServiceWorkersOnMainThreadForTesting:(BOOL)shouldRunOnMainThread
+{
+ _configuration->setShouldRunServiceWorkersOnMainThreadForTesting(shouldRunOnMainThread);
+}
+
- (void)setProxyConfiguration:(NSDictionary *)configuration
{
_configuration->setProxyConfiguration((__bridge CFDictionaryRef)[configuration copy]);
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (283294 => 283295)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -2058,6 +2058,7 @@
networkSessionParameters.allowsServerPreconnect = m_configuration->allowsServerPreconnect();
networkSessionParameters.resourceLoadStatisticsParameters = WTFMove(resourceLoadStatisticsParameters);
networkSessionParameters.requiresSecureHTTPSProxyConnection = m_configuration->requiresSecureHTTPSProxyConnection();
+ networkSessionParameters.shouldRunServiceWorkersOnMainThreadForTesting = m_configuration->shouldRunServiceWorkersOnMainThreadForTesting();
networkSessionParameters.preventsSystemHTTPProxyAuthentication = m_configuration->preventsSystemHTTPProxyAuthentication();
networkSessionParameters.allowsHSTSWithUntrustedRootCertificate = m_configuration->allowsHSTSWithUntrustedRootCertificate();
networkSessionParameters.pcmMachServiceName = m_configuration->pcmMachServiceName();
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (283294 => 283295)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -97,6 +97,7 @@
copy->m_suppressesConnectionTerminationOnSystemChange = this->m_suppressesConnectionTerminationOnSystemChange;
copy->m_allowsServerPreconnect = this->m_allowsServerPreconnect;
copy->m_requiresSecureHTTPSProxyConnection = this->m_requiresSecureHTTPSProxyConnection;
+ copy->m_shouldRunServiceWorkersOnMainThreadForTesting = this->m_shouldRunServiceWorkersOnMainThreadForTesting;
copy->m_preventsSystemHTTPProxyAuthentication = this->m_preventsSystemHTTPProxyAuthentication;
copy->m_standaloneApplicationURL = this->m_standaloneApplicationURL;
copy->m_enableInAppBrowserPrivacyForTesting = this->m_enableInAppBrowserPrivacyForTesting;
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (283294 => 283295)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -171,6 +171,9 @@
bool requiresSecureHTTPSProxyConnection() const { return m_requiresSecureHTTPSProxyConnection; };
void setRequiresSecureHTTPSProxyConnection(bool requires) { m_requiresSecureHTTPSProxyConnection = requires; }
+ bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
+ void setShouldRunServiceWorkersOnMainThreadForTesting(bool shouldRunOnMainThread) { m_shouldRunServiceWorkersOnMainThreadForTesting = shouldRunOnMainThread; }
+
const URL& standaloneApplicationURL() const { return m_standaloneApplicationURL; }
void setStandaloneApplicationURL(URL&& url) { m_standaloneApplicationURL = WTFMove(url); }
@@ -231,6 +234,7 @@
bool m_allowsServerPreconnect { true };
bool m_preventsSystemHTTPProxyAuthentication { false };
bool m_requiresSecureHTTPSProxyConnection { false };
+ bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
unsigned m_testSpeedMultiplier { 1 };
URL m_standaloneApplicationURL;
bool m_enableInAppBrowserPrivacyForTesting { false };
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (283294 => 283295)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-09-30 02:19:59 UTC (rev 283295)
@@ -141,7 +141,7 @@
serviceWorkerThreadProxy->setLastNavigationWasAppInitiated(lastNavigationWasAppInitiated == WebCore::LastNavigationWasAppInitiated::Yes);
}
-void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent)
+void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode)
{
auto pageConfiguration = pageConfigurationWithEmptyClients(WebProcess::singleton().sessionID());
@@ -163,7 +163,7 @@
#endif
auto lastNavigationWasAppInitiated = contextData.lastNavigationWasAppInitiated;
- auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), WTFMove(contextData), WTFMove(workerData), WTFMove(effectiveUserAgent), WebProcess::singleton().cacheStorageProvider(), m_storageBlockingPolicy);
+ auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), WTFMove(contextData), WTFMove(workerData), WTFMove(effectiveUserAgent), workerThreadMode, WebProcess::singleton().cacheStorageProvider(), m_storageBlockingPolicy);
if (lastNavigationWasAppInitiated)
serviceWorkerThreadProxy->setLastNavigationWasAppInitiated(lastNavigationWasAppInitiated == WebCore::LastNavigationWasAppInitiated::Yes);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (283294 => 283295)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-09-30 02:19:59 UTC (rev 283295)
@@ -49,6 +49,7 @@
struct FetchOptions;
class ResourceRequest;
struct ServiceWorkerContextData;
+enum class WorkerThreadMode : bool;
}
namespace WebKit {
@@ -86,7 +87,7 @@
// IPC messages.
void serviceWorkerStarted(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, bool doesHandleFetch) final;
void serviceWorkerFailedToStart(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
- void installServiceWorker(WebCore::ServiceWorkerContextData&&, WebCore::ServiceWorkerData&&, String&& userAgent);
+ void installServiceWorker(WebCore::ServiceWorkerContextData&&, WebCore::ServiceWorkerData&&, String&& userAgent, WebCore::WorkerThreadMode);
void updateAppInitiatedValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppInitiated);
void startFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
void cancelFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (283294 => 283295)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-09-30 02:19:59 UTC (rev 283295)
@@ -23,7 +23,7 @@
#if ENABLE(SERVICE_WORKER)
messages -> WebSWContextManagerConnection NotRefCounted {
- InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, struct WebCore::ServiceWorkerData workerData, String userAgent)
+ InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, struct WebCore::ServiceWorkerData workerData, String userAgent, enum:bool WebCore::WorkerThreadMode workerThreadMode)
UpdateAppInitiatedValue(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum:bool WebCore::LastNavigationWasAppInitiated lastNavigationWasAppInitiated)
StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
CancelFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier)
Modified: trunk/Tools/ChangeLog (283294 => 283295)
--- trunk/Tools/ChangeLog 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Tools/ChangeLog 2021-09-30 02:19:59 UTC (rev 283295)
@@ -1,3 +1,14 @@
+2021-09-29 Chris Dumez <[email protected]>
+
+ Add support for running service workers on the main thread
+ https://bugs.webkit.org/show_bug.cgi?id=230649
+
+ Reviewed by Alex Christensen.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+
2021-09-29 Jonathan Bedard <[email protected]>
[webkitscmpy] Contributors may be undefined
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (283294 => 283295)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm 2021-09-30 02:01:37 UTC (rev 283294)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm 2021-09-30 02:19:59 UTC (rev 283295)
@@ -420,8 +420,18 @@
)SWRESOURCE";
-TEST(ServiceWorkers, Basic)
+enum class ShouldRunServiceWorkersOnMainThread : bool { No, Yes };
+
+static void setViewDataStore(WKWebViewConfiguration* viewConfiguration, ShouldRunServiceWorkersOnMainThread shouldRunServiceWorkersOnMainThread)
{
+ auto storeConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
+ [storeConfiguration setShouldRunServiceWorkersOnMainThreadForTesting:shouldRunServiceWorkersOnMainThread == ShouldRunServiceWorkersOnMainThread::Yes];
+ auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:storeConfiguration.get()]);
+ [viewConfiguration setWebsiteDataStore:dataStore.get()];
+}
+
+static void runBasicSWTest(ShouldRunServiceWorkersOnMainThread shouldRunServiceWorkersOnMainThread)
+{
ServiceWorkerTCPServer server({
{ "text/html", mainBytes },
{ "application/_javascript_", scriptBytes},
@@ -429,18 +439,19 @@
[WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ setViewDataStore(configuration.get(), shouldRunServiceWorkersOnMainThread);
+
+ auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
// Start with a clean slate data store
- [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+ [[configuration websiteDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
done = true;
}];
TestWebKitAPI::Util::run(&done);
done = false;
- auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-
- auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
- [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
-
auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
[webView loadRequest:server.request()];
@@ -450,7 +461,7 @@
webView = nullptr;
- [[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
+ [[configuration websiteDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
EXPECT_EQ(1u, [websiteDataRecords count]);
EXPECT_WK_STREQ(websiteDataRecords[0].displayName, "127.0.0.1");
@@ -461,6 +472,16 @@
done = false;
}
+TEST(ServiceWorkers, Basic)
+{
+ runBasicSWTest(ShouldRunServiceWorkersOnMainThread::No);
+}
+
+TEST(ServiceWorkers, BasicWithMainThreadSW)
+{
+ runBasicSWTest(ShouldRunServiceWorkersOnMainThread::Yes);
+}
+
@interface SWCustomUserAgentDelegate : NSObject <WKNavigationDelegate> {
NSString *_userAgent;
}
@@ -767,6 +788,58 @@
done = false;
}
+TEST(ServiceWorkers, MainThreadSWInterceptsLoad)
+{
+ [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ setViewDataStore(configuration.get(), ShouldRunServiceWorkersOnMainThread::Yes);
+
+ RetainPtr<WKWebsiteDataStore> dataStore = [configuration websiteDataStore];
+
+ // Start with a clean slate data store
+ [dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+ ServiceWorkerTCPServer server({
+ { "text/html", mainForFirstLoadInterceptTestBytes },
+ { "application/_javascript_", scriptInterceptingFirstLoadBytes },
+ }, {
+ { "application/_javascript_", scriptInterceptingFirstLoadBytes },
+ });
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ expectedMessage = "Service Worker activated";
+ [webView loadRequest:server.request()];
+
+ TestWebKitAPI::Util::run(&done);
+
+ webView = nullptr;
+ configuration = nullptr;
+ messageHandler = nullptr;
+
+ done = false;
+
+ configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [configuration setWebsiteDataStore:dataStore.get()];
+ messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+ webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ expectedMessage = "Intercepted by worker";
+ [webView loadRequest:server.request()];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+}
+
TEST(ServiceWorkers, WaitForPolicyDelegate)
{
[WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];