⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 283295 in webkit


Ignore:
Timestamp:
Sep 29, 2021, 7:19:59 PM (5 years ago)
Author:
Chris Dumez
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:
Location:
trunk
Files:
1 added
43 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r283287 r283295  
     12021-09-29  Chris Dumez  <cdumez@apple.com>
     2
     3        Add support for running service workers on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=230649
     5
     6        Reviewed by Alex Christensen.
     7
     8        Add support for running service workers on the main thread (off by default).
     9
     10        This is to support use cases where the InjectedBundle needs to have access
     11        to a service worker's JS global object and script it. It wouldn't be practical
     12        in such cases to have the service worker running off the main thread. Note that
     13        this is not meant to be used for service workers in general, only for some very
     14        specific service workers that require interaction with WebKit's injected bundle.
     15
     16        * Headers.cmake:
     17        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
     18        (WebCore::IDBClient::IDBConnectionProxy::forgetActivityForCurrentThread):
     19        * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
     20        (WebCore::WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion):
     21        * WebCore.xcodeproj/project.pbxproj:
     22        * inspector/WorkerDebugger.cpp:
     23        (WebCore::WorkerDebugger::runEventLoopWhilePaused):
     24        * loader/WorkerThreadableLoader.cpp:
     25        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
     26        * page/PerformanceUserTiming.cpp:
     27        (WebCore::PerformanceUserTiming::convertMarkToTimestamp const):
     28        * workers/WorkerOrWorkletGlobalScope.h:
     29        * workers/WorkerOrWorkletScriptController.cpp:
     30        (WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously):
     31        * workers/WorkerOrWorkletScriptController.h:
     32        * workers/WorkerOrWorkletThread.cpp:
     33        (WebCore::constructRunLoop):
     34        (WebCore::WorkerOrWorkletThread::WorkerOrWorkletThread):
     35        (WebCore::WorkerOrWorkletThread::startRunningDebuggerTasks):
     36        (WebCore::WorkerOrWorkletThread::runEventLoop):
     37        (WebCore::WorkerOrWorkletThread::workerOrWorkletThread):
     38        (WebCore::WorkerOrWorkletThread::stop):
     39        (WebCore::WorkerOrWorkletThread::suspend):
     40        (WebCore::WorkerOrWorkletThread::resume):
     41        * workers/WorkerOrWorkletThread.h:
     42        * workers/WorkerRunLoop.cpp:
     43        (WebCore::ModePredicate::operator() const):
     44        (WebCore::WorkerDedicatedRunLoop::WorkerDedicatedRunLoop):
     45        (WebCore::WorkerDedicatedRunLoop::~WorkerDedicatedRunLoop):
     46        (WebCore::RunLoopSetup::RunLoopSetup):
     47        (WebCore::WorkerDedicatedRunLoop::run):
     48        (WebCore::WorkerDedicatedRunLoop::runInDebuggerMode):
     49        (WebCore::WorkerDedicatedRunLoop::runInMode):
     50        (WebCore::WorkerDedicatedRunLoop::runCleanupTasks):
     51        (WebCore::WorkerDedicatedRunLoop::terminate):
     52        (WebCore::WorkerDedicatedRunLoop::postTaskAndTerminate):
     53        (WebCore::WorkerDedicatedRunLoop::postTaskForMode):
     54        (WebCore::WorkerDedicatedRunLoop::Task::performTask):
     55        (WebCore::WorkerDedicatedRunLoop::Task::Task):
     56        (WebCore::WorkerMainRunLoop::WorkerMainRunLoop):
     57        (WebCore::WorkerMainRunLoop::setGlobalScope):
     58        (WebCore::WorkerMainRunLoop::postTaskAndTerminate):
     59        (WebCore::WorkerMainRunLoop::postTaskForMode):
     60        (WebCore::WorkerMainRunLoop::runInMode):
     61        * workers/WorkerRunLoop.h:
     62        (WebCore::WorkerRunLoop::createUniqueId):
     63        (isType):
     64        * workers/WorkerThread.cpp:
     65        (WebCore::WorkerParameters::isolatedCopy const):
     66        (WebCore::WorkerThread::WorkerThread):
     67        (WebCore::WorkerThread::createThread):
     68        (WebCore::WorkerThread::evaluateScriptIfNecessary):
     69        * workers/WorkerThread.h:
     70        * workers/WorkerThreadMode.h: Added.
     71        * workers/service/ServiceWorkerGlobalScope.cpp:
     72        (WebCore::ServiceWorkerGlobalScope::updateExtendedEventsSet):
     73        * workers/service/context/ServiceWorkerThread.cpp:
     74        (WebCore::generateWorkerParameters):
     75        (WebCore::ServiceWorkerThread::ServiceWorkerThread):
     76        (WebCore::ServiceWorkerThread::finishedEvaluatingScript):
     77        (WebCore::ServiceWorkerThread::startHeartBeatTimer):
     78        * workers/service/context/ServiceWorkerThread.h:
     79        * workers/service/context/ServiceWorkerThreadProxy.cpp:
     80        (WebCore::ServiceWorkerThreadProxy::ServiceWorkerThreadProxy):
     81        * workers/service/context/ServiceWorkerThreadProxy.h:
     82        * workers/service/server/SWServer.cpp:
     83        (WebCore::SWServer::SWServer):
     84        (WebCore::SWServer::installContextData):
     85        (WebCore::SWServer::runServiceWorker):
     86        * workers/service/server/SWServer.h:
     87        * workers/service/server/SWServerToContextConnection.h:
     88
    1892021-09-29  Basuke Suzuki  <basuke.suzuki@sony.com>
    290
  • trunk/Source/WebCore/Headers.cmake

    r283271 r283295  
    17321732    workers/WorkerScriptLoaderClient.h
    17331733    workers/WorkerThread.h
     1734    workers/WorkerThreadMode.h
    17341735    workers/WorkerThreadType.h
    17351736    workers/WorkerType.h
  • trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp

    r280053 r283295  
    610610void IDBConnectionProxy::forgetActivityForCurrentThread()
    611611{
    612     ASSERT(!isMainThread());
    613 
    614612    {
    615613        Locker locker { m_databaseConnectionMapLock };
  • trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp

    r282818 r283295  
    593593        return;
    594594    WorkerRunLoop& runLoop = m_workerGlobalScope->thread().runLoop();
    595     MessageQueueWaitResult result = MessageQueueMessageReceived;
     595    bool success = true;
    596596    ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.ptr();
    597     while (m_workerGlobalScope && clientWrapper && !clientWrapper->syncMethodDone() && result != MessageQueueTerminated) {
    598         result = runLoop.runInMode(m_workerGlobalScope.get(), m_taskMode); // May cause this bridge to get disconnected, which makes m_workerGlobalScope become null.
     597    while (m_workerGlobalScope && clientWrapper && !clientWrapper->syncMethodDone() && success) {
     598        success = runLoop.runInMode(m_workerGlobalScope.get(), m_taskMode); // May cause this bridge to get disconnected, which makes m_workerGlobalScope become null.
    599599        clientWrapper = m_workerClientWrapper.ptr();
    600600    }
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r283271 r283295  
    13141314                463521AD2081092A00C28922 /* WindowProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 463521AA2081090B00C28922 /* WindowProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
    13151315                463EB6231B8789E00096ED51 /* TagCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 463EB6211B8789CB0096ED51 /* TagCollection.h */; };
     1316                4650AD1926FCCA650047F7AD /* WorkerThreadMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    13161317                465307D01DB6EE4800E4137C /* JSUIEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E045EF1DAA104F00B0D8B9 /* JSUIEventInit.h */; };
    13171318                46658DC91FA24B8700F7DD54 /* SWContextManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4672413B1FA24B140088BD6D /* SWContextManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    84538454                463EB6211B8789CB0096ED51 /* TagCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagCollection.h; sourceTree = "<group>"; };
    84548455                4642404520EAF0ED00B29FD2 /* DatabaseManagerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseManagerCocoa.mm; sourceTree = "<group>"; };
     8456                4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerThreadMode.h; sourceTree = "<group>"; };
    84558457                465A8E781C8A24CE00E7D3E4 /* RuntimeApplicationChecksCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RuntimeApplicationChecksCocoa.mm; sourceTree = "<group>"; };
    84568458                465EDD9F222F4EC300B46E16 /* DeviceOrientationOrMotionPermissionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceOrientationOrMotionPermissionState.h; sourceTree = "<group>"; };
     
    1950519507                                2E4346420F546A8200B0F1BA /* WorkerThread.cpp */,
    1950619508                                2E4346430F546A8200B0F1BA /* WorkerThread.h */,
     19509                                4650AD1726FCCA5A0047F7AD /* WorkerThreadMode.h */,
    1950719510                                E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */,
    1950819511                                51F174FC1F35898800C74950 /* WorkerType.h */,
     
    3597635979                                0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */,
    3597735980                                97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */,
     35981                                4650AD1926FCCA650047F7AD /* WorkerThreadMode.h in Headers */,
    3597835982                                E3AFD7AD255F50EB00E5E30E /* WorkerThreadType.h in Headers */,
    3597935983                                A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */,
  • trunk/Source/WebCore/inspector/WorkerDebugger.cpp

    r268900 r283295  
    8080    TimerBase::fireTimersInNestedEventLoop();
    8181
     82    // FIXME: Add support for pausing workers running on the main thread.
     83    if (!is<WorkerDedicatedRunLoop>(m_globalScope.workerOrWorkletThread()->runLoop()))
     84        return;
     85
    8286    MessageQueueWaitResult result;
    8387    do {
    84         result = m_globalScope.workerOrWorkletThread()->runLoop().runInDebuggerMode(m_globalScope);
     88        result = downcast<WorkerDedicatedRunLoop>(m_globalScope.workerOrWorkletThread()->runLoop()).runInDebuggerMode(m_globalScope);
    8589    } while (result != MessageQueueTerminated && !doneProcessingDebuggerEvents());
    8690}
  • trunk/Source/WebCore/loader/WorkerThreadableLoader.cpp

    r282860 r283295  
    7575
    7676    auto loader = WorkerThreadableLoader::create(workerOrWorkletGlobalScope, client, mode, WTFMove(request), options, String());
    77     MessageQueueWaitResult result = MessageQueueMessageReceived;
    78     while (!loader->done() && result != MessageQueueTerminated)
    79         result = runLoop.runInMode(&workerOrWorkletGlobalScope, mode);
    80 
    81     if (!loader->done() && result == MessageQueueTerminated)
     77    bool success = true;
     78    while (!loader->done() && success)
     79        success = runLoop.runInMode(&workerOrWorkletGlobalScope, mode);
     80
     81    if (!loader->done() && !success)
    8282        loader->cancel();
    8383}
  • trunk/Source/WebCore/page/PerformanceUserTiming.cpp

    r278253 r283295  
    138138ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(const String& mark) const
    139139{
    140     if (!is<Document>(m_performance.scriptExecutionContext())) {
     140    if (!isMainThread()) {
    141141        if (isRestrictedMarkNameNonMainThread(mark))
    142142            return Exception { TypeError };
  • trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h

    r282712 r283295  
    4545public:
    4646    virtual ~WorkerOrWorkletGlobalScope();
     47
     48    using ScriptExecutionContext::weakPtrFactory;
     49    using WeakValueType = ScriptExecutionContext::WeakValueType;
    4750
    4851    bool isClosing() const { return m_isClosing; }
  • trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp

    r282860 r283295  
    268268}
    269269
    270 MessageQueueWaitResult WorkerOrWorkletScriptController::loadModuleSynchronously(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode)
     270bool WorkerOrWorkletScriptController::loadModuleSynchronously(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode)
    271271{
    272272    if (isExecutionForbidden())
    273         return MessageQueueTerminated;
     273        return false;
    274274
    275275    initScriptIfNeeded();
     
    341341    // in the following driving of the RunLoop which mainly attempt to collect initial load of module scripts.
    342342    String taskMode = WorkerModuleScriptLoader::taskMode();
    343     MessageQueueWaitResult result = MessageQueueMessageReceived;
    344     while ((!protector->isLoaded() && !protector->wasCanceled()) && result != MessageQueueTerminated) {
    345         result = runLoop.runInMode(m_globalScope, taskMode);
    346         if (result != MessageQueueTerminated)
     343    bool success = true;
     344    while ((!protector->isLoaded() && !protector->wasCanceled()) && success) {
     345        success = runLoop.runInMode(m_globalScope, taskMode);
     346        if (success)
    347347            m_globalScope->eventLoop().performMicrotaskCheckpoint();
    348348    }
    349349
    350     return result;
     350    return success;
    351351}
    352352
  • trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h

    r278253 r283295  
    100100
    101101    void linkAndEvaluateModule(WorkerScriptFetcher&, const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
    102     MessageQueueWaitResult loadModuleSynchronously(WorkerScriptFetcher&, const ScriptSourceCode&);
     102    bool loadModuleSynchronously(WorkerScriptFetcher&, const ScriptSourceCode&);
    103103
    104104    void loadAndEvaluateModule(const URL& moduleURL, FetchOptions::Credentials, CompletionHandler<void(std::optional<Exception>&&)>&&);
  • trunk/Source/WebCore/workers/WorkerOrWorkletThread.cpp

    r282755 r283295  
    2828
    2929#include "ThreadGlobalData.h"
     30#include "WorkerEventLoop.h"
    3031#include "WorkerOrWorkletGlobalScope.h"
    3132#include "WorkerOrWorkletScriptController.h"
     
    5556}
    5657
    57 WorkerOrWorkletThread::WorkerOrWorkletThread(const String& identifier)
     58static UniqueRef<WorkerRunLoop> constructRunLoop(WorkerThreadMode workerThreadMode)
     59{
     60    switch (workerThreadMode) {
     61    case WorkerThreadMode::UseMainThread:
     62        return makeUniqueRef<WorkerMainRunLoop>();
     63    case WorkerThreadMode::CreateNewThread:
     64        break;
     65    }
     66    return makeUniqueRef<WorkerDedicatedRunLoop>();
     67}
     68
     69WorkerOrWorkletThread::WorkerOrWorkletThread(const String& identifier, WorkerThreadMode workerThreadMode)
    5870    : m_identifier(identifier)
     71    , m_runLoop(constructRunLoop(workerThreadMode))
    5972{
    6073    Locker locker { workerOrWorkletThreadsLock() };
     
    7487    m_pausedForDebugger = true;
    7588
     89    // FIXME: Add support for debugging workers running on the main thread.
     90    if (!is<WorkerDedicatedRunLoop>(m_runLoop.get()))
     91        return;
     92
    7693    MessageQueueWaitResult result;
    7794    do {
    78         result = m_runLoop.runInDebuggerMode(*m_globalScope);
     95        result = downcast<WorkerDedicatedRunLoop>(m_runLoop.get()).runInDebuggerMode(*m_globalScope);
    7996    } while (result != MessageQueueTerminated && m_pausedForDebugger);
    8097}
     
    88105{
    89106    // Does not return until terminated.
    90     m_runLoop.run(m_globalScope.get());
     107    if (is<WorkerDedicatedRunLoop>(m_runLoop.get()))
     108        downcast<WorkerDedicatedRunLoop>(m_runLoop.get()).run(m_globalScope.get());
    91109}
    92110
     
    94112{
    95113    Ref protectedThis { *this };
     114
     115    if (isMainThread()) {
     116        m_globalScope = createGlobalScope();
     117        if (!m_globalScope)
     118            return;
     119
     120        downcast<WorkerMainRunLoop>(m_runLoop.get()).setGlobalScope(*m_globalScope);
     121
     122        String exceptionMessage;
     123        evaluateScriptIfNecessary(exceptionMessage);
     124
     125        callOnMainThread([evaluateCallback = WTFMove(m_evaluateCallback), message = WTFMove(exceptionMessage)] {
     126            if (evaluateCallback)
     127                evaluateCallback(message);
     128        });
     129        return;
     130    }
    96131
    97132    // Propagate the mainThread's fenv to workers.
     
    121156        scriptController = m_globalScope->script();
    122157
    123         if (m_runLoop.terminated()) {
     158        if (m_runLoop->terminated()) {
    124159            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
    125160            // forbidExecution() couldn't be called from stop().
     
    133168
    134169        // If the worker was somehow terminated while processing debugger commands.
    135         if (m_runLoop.terminated())
     170        if (m_runLoop->terminated())
    136171            scriptController->forbidExecution();
    137172    }
     
    229264        globalScope()->script()->scheduleExecutionTermination();
    230265
    231         m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
     266        if (is<WorkerMainRunLoop>(m_runLoop.get())) {
     267            auto globalScope = std::exchange(m_globalScope, nullptr);
     268            globalScope->prepareForDestruction();
     269            globalScope->clearScript();
     270            m_runLoop->terminate();
     271
     272            if (m_stoppedCallback)
     273                callOnMainThread(std::exchange(m_stoppedCallback, nullptr));
     274            return;
     275        }
     276
     277        m_runLoop->postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
    232278            auto& globalScope = downcast<WorkerOrWorkletGlobalScope>(context);
    233279
     
    245291        return;
    246292    }
    247     m_runLoop.terminate();
     293    m_runLoop->terminate();
    248294}
    249295
     
    251297{
    252298    m_isSuspended = true;
    253     m_runLoop.postTask([&](ScriptExecutionContext&) {
     299    if (is<WorkerMainRunLoop>(m_runLoop.get()))
     300        return;
     301
     302    m_runLoop->postTask([&](ScriptExecutionContext&) {
    254303        if (globalScope())
    255304            globalScope()->suspend();
     
    266315    ASSERT(m_isSuspended);
    267316    m_isSuspended = false;
     317    if (is<WorkerMainRunLoop>(m_runLoop.get()))
     318        return;
     319
    268320    m_suspensionSemaphore.signal();
    269321}
  • trunk/Source/WebCore/workers/WorkerOrWorkletThread.h

    r277958 r283295  
    2727
    2828#include "WorkerRunLoop.h"
     29#include "WorkerThreadMode.h"
    2930#include <wtf/Forward.h>
    3031#include <wtf/Function.h>
     
    4142class WorkerDebuggerProxy;
    4243class WorkerLoaderProxy;
    43 class WorkerRunLoop;
    4444
    4545class WorkerOrWorkletThread : public ThreadSafeRefCounted<WorkerOrWorkletThread> {
     
    7171
    7272protected:
    73     explicit WorkerOrWorkletThread(const String& identifier);
     73    explicit WorkerOrWorkletThread(const String& identifier, WorkerThreadMode = WorkerThreadMode::CreateNewThread);
    7474    void workerOrWorkletThread();
    7575
     
    8989    RefPtr<WorkerOrWorkletGlobalScope> m_globalScope;
    9090    RefPtr<WTF::Thread> m_thread;
    91     WorkerRunLoop m_runLoop;
     91    UniqueRef<WorkerRunLoop> m_runLoop;
    9292    Function<void(const String&)> m_evaluateCallback;
    9393    Function<void()> m_stoppedCallback;
  • trunk/Source/WebCore/workers/WorkerRunLoop.cpp

    r268517 r283295  
    11/*
    22 * Copyright (C) 2009 Google Inc. All rights reserved.
    3  * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
     3 * Copyright (C) 2016-2021 Apple Inc.  All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    7777    }
    7878
    79     bool operator()(const WorkerRunLoop::Task& task) const
     79    bool operator()(const WorkerDedicatedRunLoop::Task& task) const
    8080    {
    8181        return m_defaultMode || m_mode == task.mode();
     
    8787};
    8888
    89 WorkerRunLoop::WorkerRunLoop()
     89WorkerDedicatedRunLoop::WorkerDedicatedRunLoop()
    9090    : m_sharedTimer(makeUnique<WorkerSharedTimer>())
    9191{
    9292}
    9393
    94 WorkerRunLoop::~WorkerRunLoop()
     94WorkerDedicatedRunLoop::~WorkerDedicatedRunLoop()
    9595{
    9696    ASSERT(!m_nestedCount);
     
    111111public:
    112112    enum class IsForDebugging { No, Yes };
    113     RunLoopSetup(WorkerRunLoop& runLoop, IsForDebugging isForDebugging)
     113    RunLoopSetup(WorkerDedicatedRunLoop& runLoop, IsForDebugging isForDebugging)
    114114        : m_runLoop(runLoop)
    115115        , m_isForDebugging(isForDebugging)
     
    131131    }
    132132private:
    133     WorkerRunLoop& m_runLoop;
     133    WorkerDedicatedRunLoop& m_runLoop;
    134134    IsForDebugging m_isForDebugging { IsForDebugging::No };
    135135};
    136136
    137 void WorkerRunLoop::run(WorkerOrWorkletGlobalScope* context)
     137void WorkerDedicatedRunLoop::run(WorkerOrWorkletGlobalScope* context)
    138138{
    139139    RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No);
     
    141141    MessageQueueWaitResult result;
    142142    do {
    143         result = runInMode(context, modePredicate, WaitForMessage);
     143        result = runInMode(context, modePredicate);
    144144    } while (result != MessageQueueTerminated);
    145145    runCleanupTasks(context);
    146146}
    147147
    148 MessageQueueWaitResult WorkerRunLoop::runInDebuggerMode(WorkerOrWorkletGlobalScope& context)
     148MessageQueueWaitResult WorkerDedicatedRunLoop::runInDebuggerMode(WorkerOrWorkletGlobalScope& context)
    149149{
    150150    RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::Yes);
    151     return runInMode(&context, ModePredicate { debuggerMode() }, WaitForMessage);
    152 }
    153 
    154 MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode, WaitMode waitMode)
     151    return runInMode(&context, ModePredicate { debuggerMode() });
     152}
     153
     154bool WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const String& mode)
    155155{
    156156    ASSERT(mode != debuggerMode());
    157157    RunLoopSetup setup(*this, RunLoopSetup::IsForDebugging::No);
    158158    ModePredicate modePredicate(String { mode });
    159     MessageQueueWaitResult result = runInMode(context, modePredicate, waitMode);
    160     return result;
    161 }
    162 
    163 MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode)
     159    return runInMode(context, modePredicate) != MessageQueueWaitResult::MessageQueueTerminated;
     160}
     161
     162MessageQueueWaitResult WorkerDedicatedRunLoop::runInMode(WorkerOrWorkletGlobalScope* context, const ModePredicate& predicate)
    164163{
    165164    ASSERT(context);
     
    186185#endif
    187186
    188     if (waitMode == WaitForMessage && predicate.isDefaultMode() && m_sharedTimer->isActive())
     187    if (predicate.isDefaultMode() && m_sharedTimer->isActive())
    189188        timeoutDelay = std::min(timeoutDelay, m_sharedTimer->fireTimeDelay());
    190189
     
    226225}
    227226
    228 void WorkerRunLoop::runCleanupTasks(WorkerOrWorkletGlobalScope* context)
     227void WorkerDedicatedRunLoop::runCleanupTasks(WorkerOrWorkletGlobalScope* context)
    229228{
    230229    ASSERT(context);
     
    240239}
    241240
    242 void WorkerRunLoop::terminate()
     241void WorkerDedicatedRunLoop::terminate()
    243242{
    244243    m_messageQueue.kill();
     
    250249}
    251250
    252 void WorkerRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
     251void WorkerDedicatedRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
    253252{
    254253    m_messageQueue.appendAndKill(makeUnique<Task>(WTFMove(task), defaultMode()));
    255254}
    256255
    257 void WorkerRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& mode)
     256void WorkerDedicatedRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& mode)
    258257{
    259258    m_messageQueue.append(makeUnique<Task>(WTFMove(task), mode));
     
    265264}
    266265
    267 void WorkerRunLoop::Task::performTask(WorkerOrWorkletGlobalScope* context)
     266void WorkerDedicatedRunLoop::Task::performTask(WorkerOrWorkletGlobalScope* context)
    268267{
    269268    if ((!context->isClosing() && context->script() && !context->script()->isTerminatingExecution()) || m_task.isCleanupTask())
     
    271270}
    272271
    273 WorkerRunLoop::Task::Task(ScriptExecutionContext::Task&& task, const String& mode)
     272WorkerDedicatedRunLoop::Task::Task(ScriptExecutionContext::Task&& task, const String& mode)
    274273    : m_task(WTFMove(task))
    275274    , m_mode(mode.isolatedCopy())
     
    277276}
    278277
     278WorkerMainRunLoop::WorkerMainRunLoop()
     279{
     280}
     281
     282void WorkerMainRunLoop::setGlobalScope(WorkerOrWorkletGlobalScope& globalScope)
     283{
     284    m_workerOrWorkletGlobalScope = makeWeakPtr(globalScope);
     285}
     286
     287void WorkerMainRunLoop::postTaskAndTerminate(ScriptExecutionContext::Task&& task)
     288{
     289    if (m_terminated)
     290        return;
     291
     292    RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), task = WTFMove(task)]() mutable {
     293        if (!weakThis || !weakThis->m_workerOrWorkletGlobalScope || weakThis->m_terminated)
     294            return;
     295
     296        weakThis->m_terminated = true;
     297        task.performTask(*weakThis->m_workerOrWorkletGlobalScope);
     298    });
     299}
     300
     301void WorkerMainRunLoop::postTaskForMode(ScriptExecutionContext::Task&& task, const String& /*mode*/)
     302{
     303    if (m_terminated)
     304        return;
     305
     306    RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), task = WTFMove(task)]() mutable {
     307        if (!weakThis || !weakThis->m_workerOrWorkletGlobalScope || weakThis->m_terminated)
     308            return;
     309
     310        task.performTask(*weakThis->m_workerOrWorkletGlobalScope);
     311    });
     312}
     313
     314bool WorkerMainRunLoop::runInMode(WorkerOrWorkletGlobalScope*, const String&)
     315{
     316    RunLoop::main().cycle();
     317    return true;
     318}
     319
    279320} // namespace WebCore
  • trunk/Source/WebCore/workers/WorkerRunLoop.h

    r281348 r283295  
    11/*
    22 * Copyright (C) 2009 Google Inc. All rights reserved.
    3  * Copyright (C) 2017 Apple Inc.  All rights reserved.
     3 * Copyright (C) 2017-2021 Apple Inc.  All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    4343
    4444class WorkerRunLoop {
     45    WTF_MAKE_FAST_ALLOCATED;
    4546public:
    46     WorkerRunLoop();
    47     ~WorkerRunLoop();
     47    enum class Type : bool { WorkerDedicatedRunLoop, WorkerMainRunLoop };
     48
     49    virtual ~WorkerRunLoop() = default;
     50
     51    virtual bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode) = 0;
     52    virtual void postTaskAndTerminate(ScriptExecutionContext::Task&&) = 0;
     53    virtual void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) = 0;
     54    virtual void terminate() = 0;
     55    virtual bool terminated() const = 0;
     56    virtual Type type() const = 0;
     57
     58    void postTask(ScriptExecutionContext::Task&&);
     59    void postDebuggerTask(ScriptExecutionContext::Task&&);
     60
     61    WEBCORE_EXPORT static String defaultMode();
     62
     63    unsigned long createUniqueId() { return ++m_uniqueId; }
     64
     65private:
     66    unsigned long m_uniqueId { 0 };
     67};
     68
     69class WorkerDedicatedRunLoop final : public WorkerRunLoop {
     70public:
     71    WorkerDedicatedRunLoop();
     72    ~WorkerDedicatedRunLoop();
    4873   
    4974    // Blocking call. Waits for tasks and timers, invokes the callbacks.
    5075    void run(WorkerOrWorkletGlobalScope*);
    5176
    52     enum WaitMode { WaitForMessage, DontWaitForMessage };
    53 
    5477    // Waits for a single task and returns.
    55     MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const String& mode, WaitMode = WaitForMessage);
     78    bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode) final;
    5679    MessageQueueWaitResult runInDebuggerMode(WorkerOrWorkletGlobalScope&);
    5780
    58     void terminate();
    59     bool terminated() const { return m_messageQueue.killed(); }
     81    void terminate() final;
     82    bool terminated() const final { return m_messageQueue.killed(); }
     83    Type type() const final { return Type::WorkerDedicatedRunLoop; }
    6084
    61     void postTask(ScriptExecutionContext::Task&&);
    62     void postTaskAndTerminate(ScriptExecutionContext::Task&&);
    63     WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
    64     void postDebuggerTask(ScriptExecutionContext::Task&&);
     85    void postTaskAndTerminate(ScriptExecutionContext::Task&&) final;
     86    WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) final;
    6587
    66     unsigned long createUniqueId() { return ++m_uniqueId; }
    67 
    68     WEBCORE_EXPORT static String defaultMode();
    6988    class Task {
    7089        WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
     
    7998        String m_mode;
    8099
    81         friend class WorkerRunLoop;
     100        friend class WorkerDedicatedRunLoop;
    82101    };
    83102
    84103private:
    85104    friend class RunLoopSetup;
    86     MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const ModePredicate&, WaitMode);
     105    MessageQueueWaitResult runInMode(WorkerOrWorkletGlobalScope*, const ModePredicate&);
    87106
    88107    // Runs any clean up tasks that are currently in the queue and returns.
     
    96115    int m_nestedCount { 0 };
    97116    int m_debugCount { 0 };
    98     unsigned long m_uniqueId { 0 };
     117};
     118
     119class WorkerMainRunLoop final : public WorkerRunLoop, public CanMakeWeakPtr<WorkerMainRunLoop> {
     120public:
     121    WorkerMainRunLoop();
     122
     123    void setGlobalScope(WorkerOrWorkletGlobalScope&);
     124
     125    void terminate() final { m_terminated = true; }
     126    bool terminated() const final { return m_terminated; }
     127
     128    bool runInMode(WorkerOrWorkletGlobalScope*, const String& mode);
     129    void postTaskAndTerminate(ScriptExecutionContext::Task&&) final;
     130    void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode) final;
     131    Type type() const final { return Type::WorkerMainRunLoop; }
     132
     133private:
     134    WeakPtr<WorkerOrWorkletGlobalScope> m_workerOrWorkletGlobalScope;
     135    bool m_terminated { false };
    99136};
    100137
    101138} // namespace WebCore
     139
     140SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WorkerDedicatedRunLoop)
     141    static bool isType(const WebCore::WorkerRunLoop& runLoop) { return runLoop.type() == WebCore::WorkerRunLoop::Type::WorkerDedicatedRunLoop; }
     142SPECIALIZE_TYPE_TRAITS_END()
     143
     144SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WorkerMainRunLoop)
     145    static bool isType(const WebCore::WorkerRunLoop& runLoop) { return runLoop.type() == WebCore::WorkerRunLoop::Type::WorkerMainRunLoop; }
     146SPECIALIZE_TYPE_TRAITS_END()
  • trunk/Source/WebCore/workers/WorkerThread.cpp

    r280953 r283295  
    6161        workerType,
    6262        credentials,
    63         settingsValues.isolatedCopy()
     63        settingsValues.isolatedCopy(),
     64        workerThreadMode
    6465    };
    6566}
     
    8788
    8889WorkerThread::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)
    89     : WorkerOrWorkletThread(params.identifier.isolatedCopy())
     90    : WorkerOrWorkletThread(params.identifier.isolatedCopy(), params.workerThreadMode)
    9091    , m_workerLoaderProxy(workerLoaderProxy)
    9192    , m_workerDebuggerProxy(workerDebuggerProxy)
     
    107108Ref<Thread> WorkerThread::createThread()
    108109{
     110    if (is<WorkerMainRunLoop>(runLoop())) {
     111        // This worker should run on the main thread.
     112        RunLoop::main().dispatch([protectedThis = Ref { *this }] {
     113            protectedThis->workerOrWorkletThread();
     114        });
     115        ASSERT(isMainThread());
     116        return Thread::current();
     117    }
     118
    109119    return Thread::create(isServiceWorkerThread() ? "WebCore: Service Worker" : "WebCore: Worker", [this] {
    110120        workerOrWorkletThread();
     
    137147        ScriptSourceCode sourceCode(m_startupData->sourceCode, URL(m_startupData->params.scriptURL), { }, JSC::SourceProviderSourceType::Module, scriptFetcher.copyRef());
    138148        sourceProvider = makeWeakPtr(static_cast<ScriptBufferSourceProvider&>(sourceCode.provider()));
    139         MessageQueueWaitResult result = globalScope()->script()->loadModuleSynchronously(scriptFetcher.get(), sourceCode);
    140         if (result != MessageQueueTerminated) {
     149        bool success = globalScope()->script()->loadModuleSynchronously(scriptFetcher.get(), sourceCode);
     150        if (success) {
    141151            if (std::optional<LoadableScript::Error> error = scriptFetcher->error()) {
    142152                if (std::optional<LoadableScript::ConsoleMessage> message = error->consoleMessage)
  • trunk/Source/WebCore/workers/WorkerThread.h

    r280953 r283295  
    7373    FetchRequestCredentials credentials;
    7474    Settings::Values settingsValues;
     75    WorkerThreadMode workerThreadMode { WorkerThreadMode::CreateNewThread };
    7576
    7677    WorkerParameters isolatedCopy() const;
  • trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp

    r282860 r283295  
    115115void ServiceWorkerGlobalScope::updateExtendedEventsSet(ExtendableEvent* newEvent)
    116116{
    117     ASSERT(!isMainThread());
     117    ASSERT(isContextThread());
    118118    ASSERT(!newEvent || !newEvent->isBeingDispatched());
    119119    bool hadPendingEvents = hasPendingEvents();
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp

    r282860 r283295  
    7474// FIXME: Use valid runtime flags
    7575
    76 ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
    77     : 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())
     76static WorkerParameters generateWorkerParameters(const ServiceWorkerContextData& contextData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues)
     77{
     78    return {
     79        contextData.scriptURL,
     80        emptyString(),
     81        "serviceworker:" + Inspector::IdentifiersFactory::createIdentifier(),
     82        WTFMove(userAgent),
     83        platformStrategies()->loaderStrategy()->isOnLine(),
     84        contextData.contentSecurityPolicy,
     85        false,
     86        contextData.crossOriginEmbedderPolicy,
     87        MonotonicTime::now(),
     88        { },
     89        contextData.workerType,
     90        FetchRequestCredentials::Omit,
     91        settingsValues,
     92        workerThreadMode
     93    };
     94}
     95
     96ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider)
     97    : 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())
    7898    , m_serviceWorkerIdentifier(contextData.serviceWorkerIdentifier)
    7999    , m_jobDataIdentifier(contextData.jobDataIdentifier)
     
    195215void ServiceWorkerThread::finishedEvaluatingScript()
    196216{
    197     ASSERT(!isMainThread());
     217    ASSERT(globalScope()->isContextThread());
    198218    m_doesHandleFetch = globalScope()->hasEventListeners(eventNames().fetchEvent);
    199219}
     
    227247void ServiceWorkerThread::startHeartBeatTimer()
    228248{
     249    // We cannot detect responsiveness for service workers running on the main thread by using a main thread timer.
     250    if (is<WorkerMainRunLoop>(runLoop()))
     251        return;
     252
    229253    if (m_heartBeatTimer.isActive())
    230254        return;
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h

    r281854 r283295  
    8080
    8181private:
    82     WEBCORE_EXPORT ServiceWorkerThread(ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, const Settings::Values&, WorkerLoaderProxy&, WorkerDebuggerProxy&, IDBClient::IDBConnectionProxy*, SocketProvider*);
     82    WEBCORE_EXPORT ServiceWorkerThread(ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, WorkerThreadMode, const Settings::Values&, WorkerLoaderProxy&, WorkerDebuggerProxy&, IDBClient::IDBConnectionProxy*, SocketProvider*);
    8383
    8484    bool isServiceWorkerThread() const final { return true; }
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp

    r282860 r283295  
    9494}
    9595
    96 ServiceWorkerThreadProxy::ServiceWorkerThreadProxy(PageConfiguration&& pageConfiguration, ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, CacheStorageProvider& cacheStorageProvider, StorageBlockingPolicy storageBlockingPolicy)
     96ServiceWorkerThreadProxy::ServiceWorkerThreadProxy(PageConfiguration&& pageConfiguration, ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, CacheStorageProvider& cacheStorageProvider, StorageBlockingPolicy storageBlockingPolicy)
    9797    : m_page(createPageForServiceWorker(WTFMove(pageConfiguration), contextData, storageBlockingPolicy))
    9898    , m_document(*m_page->mainFrame().document())
     
    100100    , m_remoteDebuggable(makeUnique<ServiceWorkerDebuggable>(*this, contextData))
    101101#endif
    102     , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), m_document->settingsValues(), *this, *this, idbConnectionProxy(m_document), m_document->socketProvider()))
     102    , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), workerThreadMode, m_document->settingsValues(), *this, *this, idbConnectionProxy(m_document), m_document->socketProvider()))
    103103    , m_cacheStorageProvider(cacheStorageProvider)
    104104    , m_inspectorProxy(*this)
  • trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h

    r281854 r283295  
    5050class ServiceWorkerInspectorProxy;
    5151struct ServiceWorkerContextData;
     52enum class WorkerThreadMode : bool;
    5253
    5354class ServiceWorkerThreadProxy final : public ThreadSafeRefCounted<ServiceWorkerThreadProxy>, public WorkerLoaderProxy, public WorkerDebuggerProxy {
     
    8687
    8788private:
    88     WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, CacheStorageProvider&, StorageBlockingPolicy);
     89    WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, WorkerThreadMode, CacheStorageProvider&, StorageBlockingPolicy);
    8990
    9091    WEBCORE_EXPORT static void networkStateChanged(bool isOnLine);
  • trunk/Source/WebCore/workers/service/server/SWServer.cpp

    r283274 r283295  
    328328}
    329329
    330 SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool hasServiceWorkerEntitlement, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
     330SWServer::SWServer(UniqueRef<SWOriginStore>&& originStore, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID sessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&& softUpdateCallback, CreateContextConnectionCallback&& callback, AppBoundDomainsCallback&& appBoundDomainsCallback)
    331331    : m_originStore(WTFMove(originStore))
    332332    , m_sessionID(sessionID)
     
    335335    , m_softUpdateCallback(WTFMove(softUpdateCallback))
    336336    , m_appBoundDomainsCallback(WTFMove(appBoundDomainsCallback))
     337    , m_shouldRunServiceWorkersOnMainThreadForTesting(shouldRunServiceWorkersOnMainThreadForTesting)
    337338    , m_hasServiceWorkerEntitlement(hasServiceWorkerEntitlement)
    338339{
     
    727728    ASSERT_UNUSED(result, result.isNewEntry);
    728729
    729     connection->installServiceWorkerContext(data, worker->data(), userAgent);
     730    auto workerThreadMode = m_shouldRunServiceWorkersOnMainThreadForTesting ? WorkerThreadMode::UseMainThread : WorkerThreadMode::CreateNewThread;
     731    connection->installServiceWorkerContext(data, worker->data(), userAgent, workerThreadMode);
    730732}
    731733
     
    795797    ASSERT(contextConnection);
    796798
    797     contextConnection->installServiceWorkerContext(worker->contextData(), worker->data(), worker->userAgent());
     799    auto workerThreadMode = m_shouldRunServiceWorkersOnMainThreadForTesting ? WorkerThreadMode::UseMainThread : WorkerThreadMode::CreateNewThread;
     800    contextConnection->installServiceWorkerContext(worker->contextData(), worker->data(), worker->userAgent(), workerThreadMode);
    798801
    799802    return true;
  • trunk/Source/WebCore/workers/service/server/SWServer.h

    r280953 r283295  
    3939#include "ServiceWorkerRegistrationKey.h"
    4040#include "ServiceWorkerTypes.h"
     41#include "WorkerThreadMode.h"
    4142#include <pal/SessionID.h>
    4243#include <wtf/HashMap.h>
     
    129130    using CreateContextConnectionCallback = Function<void(const WebCore::RegistrableDomain&, CompletionHandler<void()>&&)>;
    130131    using AppBoundDomainsCallback = Function<void(CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&)>;
    131     WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool hasServiceWorkerEntitlement, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
     132    WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, SoftUpdateCallback&&, CreateContextConnectionCallback&&, AppBoundDomainsCallback&&);
    132133
    133134    WEBCORE_EXPORT ~SWServer();
     
    282283   
    283284    HashSet<WebCore::RegistrableDomain> m_appBoundDomains;
     285    bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
    284286    bool m_hasServiceWorkerEntitlement { false };
    285287    bool m_hasReceivedAppBoundDomains { false };
  • trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h

    r281854 r283295  
    4343struct ServiceWorkerContextData;
    4444struct ServiceWorkerJobDataIdentifier;
     45enum class WorkerThreadMode : bool;
    4546
    4647class SWServerToContextConnection {
     
    5253
    5354    // Messages to the SW host process
    54     virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const ServiceWorkerData&, const String& userAgent) = 0;
     55    virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const ServiceWorkerData&, const String& userAgent, WorkerThreadMode) = 0;
    5556    virtual void updateAppInitiatedValue(ServiceWorkerIdentifier, LastNavigationWasAppInitiated) = 0;
    5657    virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
  • trunk/Source/WebKit/ChangeLog

    r283294 r283295  
     12021-09-29  Chris Dumez  <cdumez@apple.com>
     2
     3        Add support for running service workers on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=230649
     5
     6        Reviewed by Alex Christensen.
     7
     8        Add support for running service workers on the main thread (off by default).
     9
     10        * NetworkProcess/NetworkProcess.cpp:
     11        (WebKit::NetworkProcess::swServerForSession):
     12        * NetworkProcess/NetworkSession.cpp:
     13        (WebKit::NetworkSession::NetworkSession):
     14        * NetworkProcess/NetworkSession.h:
     15        (WebKit::NetworkSession::shouldRunServiceWorkersOnMainThread const):
     16        * NetworkProcess/NetworkSessionCreationParameters.cpp:
     17        (WebKit::NetworkSessionCreationParameters::encode const):
     18        (WebKit::NetworkSessionCreationParameters::decode):
     19        * NetworkProcess/NetworkSessionCreationParameters.h:
     20        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
     21        (WebKit::WebSWServerToContextConnection::installServiceWorkerContext):
     22        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
     23        * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
     24        * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
     25        (-[_WKWebsiteDataStoreConfiguration shouldRunServiceWorkersOnMainThread]):
     26        (-[_WKWebsiteDataStoreConfiguration setShouldRunServiceWorkersOnMainThread:]):
     27        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     28        (WebKit::WebsiteDataStore::parameters):
     29        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
     30        (WebKit::WebsiteDataStoreConfiguration::copy const):
     31        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
     32        (WebKit::WebsiteDataStoreConfiguration::shouldRunServiceWorkersOnMainThread const):
     33        (WebKit::WebsiteDataStoreConfiguration::setShouldRunServiceWorkersOnMainThread):
     34        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
     35        (WebKit::WebSWContextManagerConnection::installServiceWorker):
     36        * WebProcess/Storage/WebSWContextManagerConnection.h:
     37        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
     38
    1392021-09-29  Alex Christensen  <achristensen@webkit.org>
    240
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r283179 r283295  
    24872487        };
    24882488#endif
    2489         return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, parentProcessHasServiceWorkerEntitlement(), [this, sessionID](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
     2489        bool shouldRunServiceWorkersOnMainThreadForTesting = false;
     2490        if (auto* session = networkSession(sessionID))
     2491            shouldRunServiceWorkersOnMainThreadForTesting = session->shouldRunServiceWorkersOnMainThreadForTesting();
     2492        return makeUnique<SWServer>(makeUniqueRef<WebSWOriginStore>(), info.processTerminationDelayEnabled, WTFMove(path), sessionID, shouldRunServiceWorkersOnMainThreadForTesting, parentProcessHasServiceWorkerEntitlement(), [this, sessionID](auto&& jobData, bool shouldRefreshCache, auto&& request, auto&& completionHandler) mutable {
    24902493            ServiceWorkerSoftUpdateLoader::start(networkSession(sessionID), WTFMove(jobData), shouldRefreshCache, WTFMove(request), WTFMove(completionHandler));
    24912494        }, [this, sessionID](auto& registrableDomain, auto&& completionHandler) {
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp

    r283179 r283295  
    119119    , m_testSpeedMultiplier(parameters.testSpeedMultiplier)
    120120    , m_allowsServerPreconnect(parameters.allowsServerPreconnect)
     121    , m_shouldRunServiceWorkersOnMainThreadForTesting(parameters.shouldRunServiceWorkersOnMainThreadForTesting)
    121122{
    122123    if (!m_sessionID.isEphemeral()) {
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.h

    r283179 r283295  
    164164    unsigned testSpeedMultiplier() const { return m_testSpeedMultiplier; }
    165165    bool allowsServerPreconnect() const { return m_allowsServerPreconnect; }
     166    bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
    166167
    167168    bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
     
    240241    unsigned m_testSpeedMultiplier { 1 };
    241242    bool m_allowsServerPreconnect { true };
     243    bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
    242244
    243245#if ENABLE(SERVICE_WORKER)
  • trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp

    r282368 r283295  
    8484    encoder << allowsServerPreconnect;
    8585    encoder << requiresSecureHTTPSProxyConnection;
     86    encoder << shouldRunServiceWorkersOnMainThreadForTesting;
    8687    encoder << preventsSystemHTTPProxyAuthentication;
    8788    encoder << appHasRequestedCrossWebsiteTrackingPermission;
     
    274275    decoder >> requiresSecureHTTPSProxyConnection;
    275276    if (!requiresSecureHTTPSProxyConnection)
     277        return std::nullopt;
     278
     279    std::optional<bool> shouldRunServiceWorkersOnMainThreadForTesting;
     280    decoder >> shouldRunServiceWorkersOnMainThreadForTesting;
     281    if (!shouldRunServiceWorkersOnMainThreadForTesting)
    276282        return std::nullopt;
    277283   
     
    350356        , WTFMove(*allowsServerPreconnect)
    351357        , WTFMove(*requiresSecureHTTPSProxyConnection)
     358        , *shouldRunServiceWorkersOnMainThreadForTesting
    352359        , WTFMove(*preventsSystemHTTPProxyAuthentication)
    353360        , WTFMove(*appHasRequestedCrossWebsiteTrackingPermission)
  • trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h

    r282368 r283295  
    9999    bool allowsServerPreconnect { true };
    100100    bool requiresSecureHTTPSProxyConnection { false };
     101    bool shouldRunServiceWorkersOnMainThreadForTesting { false };
    101102    bool preventsSystemHTTPProxyAuthentication { false };
    102103    bool appHasRequestedCrossWebsiteTrackingPermission { false };
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp

    r281854 r283295  
    8888}
    8989
    90 void WebSWServerToContextConnection::installServiceWorkerContext(const ServiceWorkerContextData& contextData, const ServiceWorkerData& workerData, const String& userAgent)
     90void WebSWServerToContextConnection::installServiceWorkerContext(const ServiceWorkerContextData& contextData, const ServiceWorkerData& workerData, const String& userAgent, WorkerThreadMode workerThreadMode)
    9191{
    92     send(Messages::WebSWContextManagerConnection::InstallServiceWorker { contextData, workerData, userAgent });
     92    send(Messages::WebSWContextManagerConnection::InstallServiceWorker { contextData, workerData, userAgent, workerThreadMode });
    9393}
    9494
  • trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h

    r281854 r283295  
    8686
    8787    // Messages to the SW host WebProcess
    88     void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const WebCore::ServiceWorkerData&, const String& userAgent) final;
     88    void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const WebCore::ServiceWorkerData&, const String& userAgent, WebCore::WorkerThreadMode) final;
    8989    void updateAppInitiatedValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppInitiated) final;
    9090    void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h

    r282368 r283295  
    5353@property (nonatomic) BOOL preventsSystemHTTPProxyAuthentication WK_API_AVAILABLE(macos(11.0), ios(14.0));
    5454@property (nonatomic) BOOL requiresSecureHTTPSProxyConnection WK_API_AVAILABLE(macos(11.0), ios(14.0));
     55@property (nonatomic) BOOL shouldRunServiceWorkersOnMainThreadForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    5556
    5657// These properties only make sense for persistent data stores, and will throw
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm

    r282368 r283295  
    487487}
    488488
     489- (BOOL)shouldRunServiceWorkersOnMainThreadForTesting
     490{
     491    return _configuration->shouldRunServiceWorkersOnMainThreadForTesting();
     492}
     493
     494- (void)setShouldRunServiceWorkersOnMainThreadForTesting:(BOOL)shouldRunOnMainThread
     495{
     496    _configuration->setShouldRunServiceWorkersOnMainThreadForTesting(shouldRunOnMainThread);
     497}
     498
    489499- (void)setProxyConfiguration:(NSDictionary *)configuration
    490500{
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r282882 r283295  
    20592059    networkSessionParameters.resourceLoadStatisticsParameters = WTFMove(resourceLoadStatisticsParameters);
    20602060    networkSessionParameters.requiresSecureHTTPSProxyConnection = m_configuration->requiresSecureHTTPSProxyConnection();
     2061    networkSessionParameters.shouldRunServiceWorkersOnMainThreadForTesting = m_configuration->shouldRunServiceWorkersOnMainThreadForTesting();
    20612062    networkSessionParameters.preventsSystemHTTPProxyAuthentication = m_configuration->preventsSystemHTTPProxyAuthentication();
    20622063    networkSessionParameters.allowsHSTSWithUntrustedRootCertificate = m_configuration->allowsHSTSWithUntrustedRootCertificate();
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp

    r282567 r283295  
    9898    copy->m_allowsServerPreconnect = this->m_allowsServerPreconnect;
    9999    copy->m_requiresSecureHTTPSProxyConnection = this->m_requiresSecureHTTPSProxyConnection;
     100    copy->m_shouldRunServiceWorkersOnMainThreadForTesting = this->m_shouldRunServiceWorkersOnMainThreadForTesting;
    100101    copy->m_preventsSystemHTTPProxyAuthentication = this->m_preventsSystemHTTPProxyAuthentication;
    101102    copy->m_standaloneApplicationURL = this->m_standaloneApplicationURL;
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h

    r282567 r283295  
    171171    bool requiresSecureHTTPSProxyConnection() const { return m_requiresSecureHTTPSProxyConnection; };
    172172    void setRequiresSecureHTTPSProxyConnection(bool requires) { m_requiresSecureHTTPSProxyConnection = requires; }
     173
     174    bool shouldRunServiceWorkersOnMainThreadForTesting() const { return m_shouldRunServiceWorkersOnMainThreadForTesting; }
     175    void setShouldRunServiceWorkersOnMainThreadForTesting(bool shouldRunOnMainThread) { m_shouldRunServiceWorkersOnMainThreadForTesting = shouldRunOnMainThread; }
    173176
    174177    const URL& standaloneApplicationURL() const { return m_standaloneApplicationURL; }
     
    232235    bool m_preventsSystemHTTPProxyAuthentication { false };
    233236    bool m_requiresSecureHTTPSProxyConnection { false };
     237    bool m_shouldRunServiceWorkersOnMainThreadForTesting { false };
    234238    unsigned m_testSpeedMultiplier { 1 };
    235239    URL m_standaloneApplicationURL;
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp

    r281854 r283295  
    142142}
    143143
    144 void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent)
     144void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode)
    145145{
    146146    auto pageConfiguration = pageConfigurationWithEmptyClients(WebProcess::singleton().sessionID());
     
    164164   
    165165    auto lastNavigationWasAppInitiated = contextData.lastNavigationWasAppInitiated;
    166     auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), WTFMove(contextData), WTFMove(workerData), WTFMove(effectiveUserAgent), WebProcess::singleton().cacheStorageProvider(), m_storageBlockingPolicy);
     166    auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), WTFMove(contextData), WTFMove(workerData), WTFMove(effectiveUserAgent), workerThreadMode, WebProcess::singleton().cacheStorageProvider(), m_storageBlockingPolicy);
    167167
    168168    if (lastNavigationWasAppInitiated)
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h

    r282712 r283295  
    5050class ResourceRequest;
    5151struct ServiceWorkerContextData;
     52enum class WorkerThreadMode : bool;
    5253}
    5354
     
    8788    void serviceWorkerStarted(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, bool doesHandleFetch) final;
    8889    void serviceWorkerFailedToStart(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
    89     void installServiceWorker(WebCore::ServiceWorkerContextData&&, WebCore::ServiceWorkerData&&, String&& userAgent);
     90    void installServiceWorker(WebCore::ServiceWorkerContextData&&, WebCore::ServiceWorkerData&&, String&& userAgent, WebCore::WorkerThreadMode);
    9091    void updateAppInitiatedValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppInitiated);
    9192    void startFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
  • trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

    r281854 r283295  
    2424
    2525messages -> WebSWContextManagerConnection NotRefCounted {
    26     InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, struct WebCore::ServiceWorkerData workerData, String userAgent)
     26    InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, struct WebCore::ServiceWorkerData workerData, String userAgent, enum:bool WebCore::WorkerThreadMode workerThreadMode)
    2727    UpdateAppInitiatedValue(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum:bool WebCore::LastNavigationWasAppInitiated lastNavigationWasAppInitiated)
    2828    StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
  • trunk/Tools/ChangeLog

    r283292 r283295  
     12021-09-29  Chris Dumez  <cdumez@apple.com>
     2
     3        Add support for running service workers on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=230649
     5
     6        Reviewed by Alex Christensen.
     7
     8        Add API test coverage.
     9
     10        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
     11
    1122021-09-29  Jonathan Bedard  <jbedard@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm

    r280992 r283295  
    421421)SWRESOURCE";
    422422
    423 TEST(ServiceWorkers, Basic)
     423enum class ShouldRunServiceWorkersOnMainThread : bool { No, Yes };
     424
     425static void setViewDataStore(WKWebViewConfiguration* viewConfiguration, ShouldRunServiceWorkersOnMainThread shouldRunServiceWorkersOnMainThread)
     426{
     427    auto storeConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
     428    [storeConfiguration setShouldRunServiceWorkersOnMainThreadForTesting:shouldRunServiceWorkersOnMainThread == ShouldRunServiceWorkersOnMainThread::Yes];
     429    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:storeConfiguration.get()]);
     430    [viewConfiguration setWebsiteDataStore:dataStore.get()];
     431}
     432
     433static void runBasicSWTest(ShouldRunServiceWorkersOnMainThread shouldRunServiceWorkersOnMainThread)
    424434{
    425435    ServiceWorkerTCPServer server({
     
    430440    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
    431441
     442    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     443    setViewDataStore(configuration.get(), shouldRunServiceWorkersOnMainThread);
     444
     445    auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
     446    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     447
    432448    // Start with a clean slate data store
    433     [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
    434         done = true;
    435     }];
    436     TestWebKitAPI::Util::run(&done);
    437     done = false;
    438 
    439     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    440 
    441     auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
    442     [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     449    [[configuration websiteDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
     450        done = true;
     451    }];
     452    TestWebKitAPI::Util::run(&done);
     453    done = false;
    443454
    444455    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     
    451462    webView = nullptr;
    452463
    453     [[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
     464    [[configuration websiteDataStore] fetchDataRecordsOfTypes:[NSSet setWithObject:WKWebsiteDataTypeServiceWorkerRegistrations] completionHandler:^(NSArray<WKWebsiteDataRecord *> *websiteDataRecords) {
    454465        EXPECT_EQ(1u, [websiteDataRecords count]);
    455466        EXPECT_WK_STREQ(websiteDataRecords[0].displayName, "127.0.0.1");
     
    460471    TestWebKitAPI::Util::run(&done);
    461472    done = false;
     473}
     474
     475TEST(ServiceWorkers, Basic)
     476{
     477    runBasicSWTest(ShouldRunServiceWorkersOnMainThread::No);
     478}
     479
     480TEST(ServiceWorkers, BasicWithMainThreadSW)
     481{
     482    runBasicSWTest(ShouldRunServiceWorkersOnMainThread::Yes);
    462483}
    463484
     
    756777
    757778    configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     779    messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
     780    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     781
     782    webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     783
     784    expectedMessage = "Intercepted by worker";
     785    [webView loadRequest:server.request()];
     786
     787    TestWebKitAPI::Util::run(&done);
     788    done = false;
     789}
     790
     791TEST(ServiceWorkers, MainThreadSWInterceptsLoad)
     792{
     793    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
     794    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     795    setViewDataStore(configuration.get(), ShouldRunServiceWorkersOnMainThread::Yes);
     796
     797    RetainPtr<WKWebsiteDataStore> dataStore = [configuration websiteDataStore];
     798
     799    // Start with a clean slate data store
     800    [dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
     801        done = true;
     802    }];
     803    TestWebKitAPI::Util::run(&done);
     804    done = false;
     805
     806    auto messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
     807    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     808
     809    ServiceWorkerTCPServer server({
     810        { "text/html", mainForFirstLoadInterceptTestBytes },
     811        { "application/javascript", scriptInterceptingFirstLoadBytes },
     812    }, {
     813        { "application/javascript", scriptInterceptingFirstLoadBytes },
     814    });
     815
     816    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     817
     818    expectedMessage = "Service Worker activated";
     819    [webView loadRequest:server.request()];
     820
     821    TestWebKitAPI::Util::run(&done);
     822
     823    webView = nullptr;
     824    configuration = nullptr;
     825    messageHandler = nullptr;
     826
     827    done = false;
     828
     829    configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     830    [configuration setWebsiteDataStore:dataStore.get()];
    758831    messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]);
    759832    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
Note: See TracChangeset for help on using the changeset viewer.