Title: [283295] trunk
Revision
283295
Author
[email protected]
Date
2021-09-29 19:19:59 -0700 (Wed, 29 Sep 2021)

Log Message

Add support for running service workers on the main thread
https://bugs.webkit.org/show_bug.cgi?id=230649

Reviewed by Alex Christensen.

Source/WebCore:

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:

Source/WebKit:

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:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:

Modified Paths

Added Paths

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];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to