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

Changeset 268822 in webkit


Ignore:
Timestamp:
Oct 21, 2020, 2:15:48 PM (6 years ago)
Author:
Chris Dumez
Message:

Share more code between WorkerGlobalScope and WorkletGlobalScope
https://bugs.webkit.org/show_bug.cgi?id=217995

Reviewed by Darin Adler.

Share more code between WorkerGlobalScope and WorkletGlobalScope by
moving shared logic to WorkerOrWorkletGlobalScope.

No new tests, no Web-facing behavior change.

  • Modules/webaudio/AudioWorkletGlobalScope.cpp:

(WebCore::AudioWorkletGlobalScope::prepareForDestruction):

  • Modules/webaudio/AudioWorkletGlobalScope.h:
  • Modules/webaudio/AudioWorkletThread.cpp:

(WebCore::AudioWorkletThread::stop):

  • workers/WorkerEventLoop.cpp:

(WebCore::WorkerEventLoop::create):
(WebCore::WorkerEventLoop::WorkerEventLoop):

  • workers/WorkerEventLoop.h:
  • workers/WorkerGlobalScope.cpp:

(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::prepareForDestruction):
(WebCore::WorkerGlobalScope::removeAllEventListeners):
(WebCore::WorkerGlobalScope::suspend):
(WebCore::WorkerGlobalScope::resume):
(WebCore::WorkerGlobalScope::close):
(WebCore::WorkerGlobalScope::wrapCryptoKey):
(WebCore::WorkerGlobalScope::unwrapCryptoKey):
(WebCore::WorkerGlobalScope::thread const):

  • workers/WorkerGlobalScope.h:
  • workers/WorkerOrWorkletGlobalScope.cpp:

(WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
(WebCore::WorkerOrWorkletGlobalScope::prepareForDestruction):
(WebCore::WorkerOrWorkletGlobalScope::disableEval):
(WebCore::WorkerOrWorkletGlobalScope::disableWebAssembly):
(WebCore::WorkerOrWorkletGlobalScope::isJSExecutionForbidden const):
(WebCore::WorkerOrWorkletGlobalScope::eventLoop):
(WebCore::WorkerOrWorkletGlobalScope::isContextThread const):
(WebCore::WorkerOrWorkletGlobalScope::postTask):

  • workers/WorkerOrWorkletGlobalScope.h:

(WebCore::WorkerOrWorkletGlobalScope::isClosing const):
(WebCore::WorkerOrWorkletGlobalScope::workerOrWorkletThread const):
(WebCore::WorkerOrWorkletGlobalScope::markAsClosing):

  • workers/WorkerThread.cpp:

(WebCore::WorkerThread::stop):

  • worklets/WorkletGlobalScope.cpp:

(WebCore::WorkletGlobalScope::WorkletGlobalScope):
(WebCore::WorkletGlobalScope::prepareForDestruction):

  • worklets/WorkletGlobalScope.h:
Location:
trunk/Source/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r268821 r268822  
     12020-10-21  Chris Dumez  <cdumez@apple.com>
     2
     3        Share more code between WorkerGlobalScope and WorkletGlobalScope
     4        https://bugs.webkit.org/show_bug.cgi?id=217995
     5
     6        Reviewed by Darin Adler.
     7
     8        Share more code between WorkerGlobalScope and WorkletGlobalScope by
     9        moving shared logic to WorkerOrWorkletGlobalScope.
     10
     11        No new tests, no Web-facing behavior change.
     12
     13        * Modules/webaudio/AudioWorkletGlobalScope.cpp:
     14        (WebCore::AudioWorkletGlobalScope::prepareForDestruction):
     15        * Modules/webaudio/AudioWorkletGlobalScope.h:
     16        * Modules/webaudio/AudioWorkletThread.cpp:
     17        (WebCore::AudioWorkletThread::stop):
     18        * workers/WorkerEventLoop.cpp:
     19        (WebCore::WorkerEventLoop::create):
     20        (WebCore::WorkerEventLoop::WorkerEventLoop):
     21        * workers/WorkerEventLoop.h:
     22        * workers/WorkerGlobalScope.cpp:
     23        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
     24        (WebCore::WorkerGlobalScope::prepareForDestruction):
     25        (WebCore::WorkerGlobalScope::removeAllEventListeners):
     26        (WebCore::WorkerGlobalScope::suspend):
     27        (WebCore::WorkerGlobalScope::resume):
     28        (WebCore::WorkerGlobalScope::close):
     29        (WebCore::WorkerGlobalScope::wrapCryptoKey):
     30        (WebCore::WorkerGlobalScope::unwrapCryptoKey):
     31        (WebCore::WorkerGlobalScope::thread const):
     32        * workers/WorkerGlobalScope.h:
     33        * workers/WorkerOrWorkletGlobalScope.cpp:
     34        (WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
     35        (WebCore::WorkerOrWorkletGlobalScope::prepareForDestruction):
     36        (WebCore::WorkerOrWorkletGlobalScope::disableEval):
     37        (WebCore::WorkerOrWorkletGlobalScope::disableWebAssembly):
     38        (WebCore::WorkerOrWorkletGlobalScope::isJSExecutionForbidden const):
     39        (WebCore::WorkerOrWorkletGlobalScope::eventLoop):
     40        (WebCore::WorkerOrWorkletGlobalScope::isContextThread const):
     41        (WebCore::WorkerOrWorkletGlobalScope::postTask):
     42        * workers/WorkerOrWorkletGlobalScope.h:
     43        (WebCore::WorkerOrWorkletGlobalScope::isClosing const):
     44        (WebCore::WorkerOrWorkletGlobalScope::workerOrWorkletThread const):
     45        (WebCore::WorkerOrWorkletGlobalScope::markAsClosing):
     46        * workers/WorkerThread.cpp:
     47        (WebCore::WorkerThread::stop):
     48        * worklets/WorkletGlobalScope.cpp:
     49        (WebCore::WorkletGlobalScope::WorkletGlobalScope):
     50        (WebCore::WorkletGlobalScope::prepareForDestruction):
     51        * worklets/WorkletGlobalScope.h:
     52
    1532020-10-21  Zalan Bujtas  <zalan@apple.com>
    254
  • trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp

    r268812 r268822  
    144144}
    145145
    146 void AudioWorkletGlobalScope::prepareForTermination()
     146void AudioWorkletGlobalScope::prepareForDestruction()
    147147{
    148     if (auto* defaultTaskGroup = this->defaultTaskGroup())
    149         defaultTaskGroup->stopAndDiscardAllTasks();
    150     stopActiveDOMObjects();
    151 
    152148    m_processorConstructorMap.clear();
    153149
    154     // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
    155     // which become dangling once Heap is destroyed.
    156     removeAllEventListeners();
    157 
    158     // MicrotaskQueue and RejectedPromiseTracker reference Heap.
    159     if (auto* eventLoop = this->existingEventLoop())
    160         eventLoop->clearMicrotaskQueue();
    161     removeRejectedPromiseTracker();
    162 }
    163 
    164 void AudioWorkletGlobalScope::postTask(Task&& task)
    165 {
    166     thread().runLoop().postTask(WTFMove(task));
     150    WorkletGlobalScope::prepareForDestruction();
    167151}
    168152
  • trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.h

    r268369 r268822  
    6262
    6363    AudioWorkletThread& thread() const;
    64     void prepareForTermination();
    65 
    66     void postTask(Task&&) final;
     64    void prepareForDestruction() final;
    6765
    6866    std::unique_ptr<AudioWorkletProcessorConstructionData> takePendingProcessorConstructionData();
  • trunk/Source/WebCore/Modules/webaudio/AudioWorkletThread.cpp

    r268775 r268822  
    8888            auto& workletGlobalScope = downcast<AudioWorkletGlobalScope>(context);
    8989
    90             workletGlobalScope.prepareForTermination();
     90            workletGlobalScope.prepareForDestruction();
    9191
    9292            // Stick a shutdown command at the end of the queue, so that we deal
  • trunk/Source/WebCore/workers/WorkerEventLoop.cpp

    r267859 r268822  
    2828
    2929#include "Microtasks.h"
    30 #include "WorkerGlobalScope.h"
    31 #include "WorkletGlobalScope.h"
     30#include "WorkerOrWorkletGlobalScope.h"
    3231
    3332namespace WebCore {
    3433
    35 Ref<WorkerEventLoop> WorkerEventLoop::create(WorkerGlobalScope& context)
     34Ref<WorkerEventLoop> WorkerEventLoop::create(WorkerOrWorkletGlobalScope& context)
    3635{
    3736    return adoptRef(*new WorkerEventLoop(context));
    3837}
    3938
    40 Ref<WorkerEventLoop> WorkerEventLoop::create(WorkletGlobalScope& context)
    41 {
    42     return adoptRef(*new WorkerEventLoop(context));
    43 }
    44 
    45 WorkerEventLoop::WorkerEventLoop(ScriptExecutionContext& context)
     39WorkerEventLoop::WorkerEventLoop(WorkerOrWorkletGlobalScope& context)
    4640    : ContextDestructionObserver(&context)
    4741{
  • trunk/Source/WebCore/workers/WorkerEventLoop.h

    r267859 r268822  
    3131namespace WebCore {
    3232
    33 class WorkerGlobalScope;
    34 class WorkletGlobalScope;
     33class WorkerOrWorkletGlobalScope;
    3534
    3635class WorkerEventLoop final : public EventLoop, private ContextDestructionObserver {
    3736public:
    38     // Explicitly take WorkerGlobalScope and WorkletGlobalScope for documentation purposes.
    39     static Ref<WorkerEventLoop> create(WorkerGlobalScope&);
    40     static Ref<WorkerEventLoop> create(WorkletGlobalScope&);
     37    static Ref<WorkerEventLoop> create(WorkerOrWorkletGlobalScope&);
    4138
    4239    virtual ~WorkerEventLoop();
     
    4643
    4744private:
    48     explicit WorkerEventLoop(ScriptExecutionContext&);
     45    explicit WorkerEventLoop(WorkerOrWorkletGlobalScope&);
    4946
    5047    void scheduleToRun() final;
  • trunk/Source/WebCore/workers/WorkerGlobalScope.cpp

    r268775 r268822  
    4444#include "ServiceWorkerGlobalScope.h"
    4545#include "SocketProvider.h"
    46 #include "WorkerEventLoop.h"
    4746#include "WorkerInspectorController.h"
    4847#include "WorkerLoaderProxy.h"
     
    6362
    6463WorkerGlobalScope::WorkerGlobalScope(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, WorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    65     : m_url(params.scriptURL)
     64    : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
     65    , m_url(params.scriptURL)
    6666    , m_identifier(params.identifier)
    6767    , m_userAgent(params.userAgent)
    68     , m_thread(thread)
    6968    , m_inspectorController(makeUnique<WorkerInspectorController>(*this))
    7069    , m_isOnline(params.isOnline)
     
    107106}
    108107
    109 EventLoopTaskGroup& WorkerGlobalScope::eventLoop()
    110 {
    111     ASSERT(isContextThread());
    112     if (UNLIKELY(!m_defaultTaskGroup)) {
    113         m_eventLoop = WorkerEventLoop::create(*this);
    114         m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
    115         if (activeDOMObjectsAreStopped())
    116             m_defaultTaskGroup->stopAndDiscardAllTasks();
    117     }
    118     return *m_defaultTaskGroup;
    119 }
    120 
    121108String WorkerGlobalScope::origin() const
    122109{
     
    125112}
    126113
    127 void WorkerGlobalScope::prepareForTermination()
    128 {
     114void WorkerGlobalScope::prepareForDestruction()
     115{
     116    WorkerOrWorkletGlobalScope::prepareForDestruction();
     117
    129118#if ENABLE(INDEXED_DATABASE)
    130119    stopIndexedDatabase();
    131120#endif
    132121
    133     if (m_defaultTaskGroup)
    134         m_defaultTaskGroup->stopAndDiscardAllTasks();
    135     stopActiveDOMObjects();
    136 
    137122    if (m_cacheStorageConnection)
    138123        m_cacheStorageConnection->clearPendingRequests();
    139124
    140125    m_inspectorController->workerTerminating();
    141 
    142     // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
    143     // which become dangling once Heap is destroyed.
    144     removeAllEventListeners();
    145 
    146     // MicrotaskQueue and RejectedPromiseTracker reference Heap.
    147     if (m_eventLoop)
    148         m_eventLoop->clearMicrotaskQueue();
    149     removeRejectedPromiseTracker();
    150126}
    151127
    152128void WorkerGlobalScope::removeAllEventListeners()
    153129{
    154     EventTarget::removeAllEventListeners();
     130    WorkerOrWorkletGlobalScope::removeAllEventListeners();
    155131    m_performance->removeAllEventListeners();
    156132    m_performance->removeAllObservers();
     
    185161}
    186162
    187 void WorkerGlobalScope::disableEval(const String& errorMessage)
    188 {
    189     script()->disableEval(errorMessage);
    190 }
    191 
    192 void WorkerGlobalScope::disableWebAssembly(const String& errorMessage)
    193 {
    194     script()->disableWebAssembly(errorMessage);
    195 }
    196 
    197163SocketProvider* WorkerGlobalScope::socketProvider()
    198164{
     
    223189#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
    224190    if (m_connectionProxy)
    225         m_connectionProxy->setContextSuspended(*scriptExecutionContext(), true);
     191        m_connectionProxy->setContextSuspended(*this, true);
    226192#endif
    227193}
     
    231197#if ENABLE(INDEXED_DATABASE_IN_WORKERS)
    232198    if (m_connectionProxy)
    233         m_connectionProxy->setContextSuspended(*scriptExecutionContext(), false);
     199        m_connectionProxy->setContextSuspended(*this, false);
    234200#endif
    235201}
     
    246212void WorkerGlobalScope::close()
    247213{
    248     if (m_closing)
     214    if (isClosing())
    249215        return;
    250216
     
    252218    // After m_closing is set, all the tasks in the queue continue to be fetched but only
    253219    // tasks with isCleanupTask()==true will be executed.
    254     m_closing = true;
     220    markAsClosing();
    255221    postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context) {
    256222        ASSERT_WITH_SECURITY_IMPLICATION(is<WorkerGlobalScope>(context));
     
    273239    if (m_navigator)
    274240        m_navigator->setIsOnline(isOnline);
    275 }
    276 
    277 void WorkerGlobalScope::postTask(Task&& task)
    278 {
    279     thread().runLoop().postTask(WTFMove(task));
    280241}
    281242
     
    407368}
    408369
    409 bool WorkerGlobalScope::isContextThread() const
    410 {
    411     return thread().thread() == &Thread::current();
    412 }
    413 
    414 bool WorkerGlobalScope::isJSExecutionForbidden() const
    415 {
    416     return script()->isExecutionForbidden();
    417 }
    418 
    419370#if ENABLE(WEB_CRYPTO)
    420371
     
    444395    auto doneContainer = CryptoBooleanContainer::create();
    445396    auto wrappedKeyContainer = CryptoBufferContainer::create();
    446     m_thread.workerLoaderProxy().postTaskToLoader([resultContainer, key, wrappedKeyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(m_thread.workerLoaderProxy()))](ScriptExecutionContext& context) {
     397    thread().workerLoaderProxy().postTaskToLoader([resultContainer, key, wrappedKeyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(thread().workerLoaderProxy()))](ScriptExecutionContext& context) {
    447398        resultContainer->setBoolean(context.wrapCryptoKey(key, wrappedKeyContainer->buffer()));
    448399        doneContainer->setBoolean(true);
     
    454405    auto waitResult = MessageQueueMessageReceived;
    455406    while (!doneContainer->boolean() && waitResult != MessageQueueTerminated)
    456         waitResult = m_thread.runLoop().runInMode(this, WorkerRunLoop::defaultMode());
     407        waitResult = thread().runLoop().runInMode(this, WorkerRunLoop::defaultMode());
    457408
    458409    if (doneContainer->boolean())
     
    467418    auto doneContainer = CryptoBooleanContainer::create();
    468419    auto keyContainer = CryptoBufferContainer::create();
    469     m_thread.workerLoaderProxy().postTaskToLoader([resultContainer, wrappedKey, keyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(m_thread.workerLoaderProxy()))](ScriptExecutionContext& context) {
     420    thread().workerLoaderProxy().postTaskToLoader([resultContainer, wrappedKey, keyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(thread().workerLoaderProxy()))](ScriptExecutionContext& context) {
    470421        resultContainer->setBoolean(context.unwrapCryptoKey(wrappedKey, keyContainer->buffer()));
    471422        doneContainer->setBoolean(true);
     
    477428    auto waitResult = MessageQueueMessageReceived;
    478429    while (!doneContainer->boolean() && waitResult != MessageQueueTerminated)
    479         waitResult = m_thread.runLoop().runInMode(this, WorkerRunLoop::defaultMode());
     430        waitResult = thread().runLoop().runInMode(this, WorkerRunLoop::defaultMode());
    480431
    481432    if (doneContainer->boolean())
     
    543494}
    544495
     496WorkerThread& WorkerGlobalScope::thread() const
     497{
     498    return *static_cast<WorkerThread*>(workerOrWorkletThread());
     499}
     500
    545501} // namespace WebCore
  • trunk/Source/WebCore/workers/WorkerGlobalScope.h

    r268775 r268822  
    2929#include "Base64Utilities.h"
    3030#include "CacheStorageConnection.h"
    31 #include "EventTarget.h"
    3231#include "ImageBitmap.h"
    3332#include "ScriptExecutionContext.h"
     
    4746class ContentSecurityPolicyResponseHeaders;
    4847class Crypto;
    49 class EventLoopTaskGroup;
    5048class Performance;
    5149class ScheduledAction;
    52 class WorkerEventLoop;
    5350class WorkerInspectorController;
    5451class WorkerLocation;
     
    6158}
    6259
    63 class WorkerGlobalScope : public RefCounted<WorkerGlobalScope>, public Supplementable<WorkerGlobalScope>, public EventTargetWithInlineData, public Base64Utilities, public WorkerOrWorkletGlobalScope {
     60class WorkerGlobalScope : public Supplementable<WorkerGlobalScope>, public Base64Utilities, public WorkerOrWorkletGlobalScope {
    6461    WTF_MAKE_ISO_ALLOCATED(WorkerGlobalScope);
    6562public:
     
    6865    virtual bool isDedicatedWorkerGlobalScope() const { return false; }
    6966    virtual bool isServiceWorkerGlobalScope() const { return false; }
    70 
    71     EventLoopTaskGroup& eventLoop() final;
    7267
    7368    const URL& url() const final { return m_url; }
     
    8984    WorkerInspectorController& inspectorController() const { return *m_inspectorController; }
    9085
    91     WorkerThread& thread() const { return m_thread; }
     86    WorkerThread& thread() const;
    9287
    9388    using ScriptExecutionContext::hasPendingActivity;
    94 
    95     void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
    9689
    9790    WorkerGlobalScope& self() { return *this; }
     
    109102    void clearInterval(int timeoutId);
    110103
    111     bool isContextThread() const final;
    112104    bool isSecureContext() const final;
    113105
     
    115107    WorkerLocation* optionalLocation() const { return m_location.get(); }
    116108
    117     using RefCounted::ref;
    118     using RefCounted::deref;
    119 
    120     bool isClosing() const final { return m_closing; }
    121 
    122109    void addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&&) final;
    123110
     
    127114    Performance& performance() const;
    128115
    129     void prepareForTermination();
     116    void prepareForDestruction() final;
    130117
    131118    void removeAllEventListeners() final;
     
    148135
    149136private:
    150     void refScriptExecutionContext() final { ref(); }
    151     void derefScriptExecutionContext() final { deref(); }
    152 
    153     void refEventTarget() final { ref(); }
    154     void derefEventTarget() final { deref(); }
    155 
    156137    void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) final;
    157138
     
    162143
    163144    bool isWorkerGlobalScope() const final { return true; }
    164     WorkerThread* workerOrWorkletThread() const final { return &m_thread; }
    165 
    166     ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkerGlobalScope*>(this); }
     145
    167146    URL completeURL(const String&, ForceUTF8 = ForceUTF8::No) const final;
    168147    String userAgent(const URL&) const final;
    169     void disableEval(const String& errorMessage) final;
    170     void disableWebAssembly(const String& errorMessage) final;
    171148    EventTarget* errorEventTarget() final;
    172149    String resourceRequestIdentifier() const final { return m_identifier; }
     
    174151
    175152    bool shouldBypassMainWorldContentSecurityPolicy() const final { return m_shouldBypassMainWorldContentSecurityPolicy; }
    176     bool isJSExecutionForbidden() const final;
    177153
    178154#if ENABLE(WEB_CRYPTO)
     
    192168    mutable RefPtr<WorkerNavigator> m_navigator;
    193169
    194     WorkerThread& m_thread;
    195170    std::unique_ptr<WorkerOrWorkletScriptController> m_script;
    196171    std::unique_ptr<WorkerInspectorController> m_inspectorController;
    197172
    198     bool m_closing { false };
    199173    bool m_isOnline;
    200174    bool m_shouldBypassMainWorldContentSecurityPolicy;
    201 
    202     RefPtr<WorkerEventLoop> m_eventLoop;
    203     std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
    204175
    205176    Ref<SecurityOrigin> m_topOrigin;
  • trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp

    r268775 r268822  
    2727#include "WorkerOrWorkletGlobalScope.h"
    2828
     29#include "WorkerEventLoop.h"
    2930#include "WorkerOrWorkletScriptController.h"
     31#include <wtf/IsoMallocInlines.h>
    3032
    3133namespace WebCore {
    3234
    33 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope()
    34     : m_script(makeUnique<WorkerOrWorkletScriptController>(this))
     35WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerOrWorkletGlobalScope);
     36
     37WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread)
     38    : m_script(makeUnique<WorkerOrWorkletScriptController>(WTFMove(vm), this))
     39    , m_thread(thread)
    3540{
    3641}
    3742
    38 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(Ref<JSC::VM>&& vm)
    39     : m_script(makeUnique<WorkerOrWorkletScriptController>(WTFMove(vm), this))
     43WorkerOrWorkletGlobalScope::~WorkerOrWorkletGlobalScope() = default;
     44
     45void WorkerOrWorkletGlobalScope::prepareForDestruction()
    4046{
     47    if (m_defaultTaskGroup)
     48        m_defaultTaskGroup->stopAndDiscardAllTasks();
     49
     50    stopActiveDOMObjects();
     51
     52    // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
     53    // which become dangling once Heap is destroyed.
     54    removeAllEventListeners();
     55
     56    // MicrotaskQueue and RejectedPromiseTracker reference Heap.
     57    if (m_eventLoop)
     58        m_eventLoop->clearMicrotaskQueue();
     59    removeRejectedPromiseTracker();
    4160}
    4261
     
    4665}
    4766
     67void WorkerOrWorkletGlobalScope::disableEval(const String& errorMessage)
     68{
     69    m_script->disableEval(errorMessage);
     70}
     71
     72void WorkerOrWorkletGlobalScope::disableWebAssembly(const String& errorMessage)
     73{
     74    m_script->disableWebAssembly(errorMessage);
     75}
     76
     77bool WorkerOrWorkletGlobalScope::isJSExecutionForbidden() const
     78{
     79    return !m_script || m_script->isExecutionForbidden();
     80}
     81
     82EventLoopTaskGroup& WorkerOrWorkletGlobalScope::eventLoop()
     83{
     84    ASSERT(isContextThread());
     85    if (UNLIKELY(!m_defaultTaskGroup)) {
     86        m_eventLoop = WorkerEventLoop::create(*this);
     87        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
     88        if (activeDOMObjectsAreStopped())
     89            m_defaultTaskGroup->stopAndDiscardAllTasks();
     90    }
     91    return *m_defaultTaskGroup;
     92}
     93
     94bool WorkerOrWorkletGlobalScope::isContextThread() const
     95{
     96    auto* thread = workerOrWorkletThread();
     97    return thread ? thread->thread() == &Thread::current() : isMainThread();
     98}
     99
     100void WorkerOrWorkletGlobalScope::postTask(Task&& task)
     101{
     102    ASSERT(workerOrWorkletThread());
     103    workerOrWorkletThread()->runLoop().postTask(WTFMove(task));
     104}
     105
    48106} // namespace WebCore
  • trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h

    r268775 r268822  
    2626#pragma once
    2727
     28#include "EventTarget.h"
    2829#include "ScriptExecutionContext.h"
    2930
    3031namespace WebCore {
    3132
     33class EventLoopTaskGroup;
     34class WorkerEventLoop;
    3235class WorkerOrWorkletScriptController;
    3336class WorkerOrWorkletThread;
    3437
    35 class WorkerOrWorkletGlobalScope : public ScriptExecutionContext {
     38class WorkerOrWorkletGlobalScope : public ScriptExecutionContext, public RefCounted<WorkerOrWorkletGlobalScope>, public EventTargetWithInlineData {
     39    WTF_MAKE_ISO_ALLOCATED(WorkerOrWorkletGlobalScope);
     40    WTF_MAKE_NONCOPYABLE(WorkerOrWorkletGlobalScope);
    3641public:
    37     virtual ~WorkerOrWorkletGlobalScope() = default;
     42    virtual ~WorkerOrWorkletGlobalScope();
    3843
    39     virtual bool isClosing() const = 0;
    40     virtual WorkerOrWorkletThread* workerOrWorkletThread() const = 0;
     44    bool isClosing() const { return m_isClosing; }
     45    WorkerOrWorkletThread* workerOrWorkletThread() const { return m_thread; }
    4146
    4247    WorkerOrWorkletScriptController* script() const { return m_script.get(); }
     
    4550    unsigned long createUniqueIdentifier() { return m_uniqueIdentifier++; }
    4651
     52    // ScriptExecutionContext.
     53    EventLoopTaskGroup& eventLoop() final;
     54    bool isContextThread() const final;
     55    void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
     56
     57    virtual void prepareForDestruction();
     58
     59    using RefCounted::ref;
     60    using RefCounted::deref;
     61
    4762protected:
    48     WorkerOrWorkletGlobalScope();
    49     explicit WorkerOrWorkletGlobalScope(Ref<JSC::VM>&&);
     63    WorkerOrWorkletGlobalScope(Ref<JSC::VM>&&, WorkerOrWorkletThread*);
     64
     65    // ScriptExecutionContext.
     66    bool isJSExecutionForbidden() const final;
     67
     68    void markAsClosing() { m_isClosing = true; }
    5069
    5170private:
     71    // ScriptExecutionContext.
     72    void disableEval(const String& errorMessage) final;
     73    void disableWebAssembly(const String& errorMessage) final;
     74    void refScriptExecutionContext() final { ref(); }
     75    void derefScriptExecutionContext() final { deref(); }
     76
     77    // EventTarget.
     78    ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkerOrWorkletGlobalScope*>(this); }
     79    void refEventTarget() final { ref(); }
     80    void derefEventTarget() final { deref(); }
     81
    5282    std::unique_ptr<WorkerOrWorkletScriptController> m_script;
     83    WorkerOrWorkletThread* m_thread;
     84    RefPtr<WorkerEventLoop> m_eventLoop;
     85    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
    5386    unsigned long m_uniqueIdentifier { 1 };
     87    bool m_isClosing { false };
    5488};
    5589
  • trunk/Source/WebCore/workers/WorkerThread.cpp

    r268775 r268822  
    321321            WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context);
    322322
    323             workerGlobalScope.prepareForTermination();
     323            workerGlobalScope.prepareForDestruction();
    324324
    325325            // Stick a shutdown command at the end of the queue, so that we deal
  • trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp

    r268775 r268822  
    3434#include "SecurityOriginPolicy.h"
    3535#include "Settings.h"
    36 #include "WorkerEventLoop.h"
    3736#include "WorkerMessagePortChannelProvider.h"
    3837#include "WorkerOrWorkletThread.h"
     
    5049
    5150WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, const WorkletParameters& parameters)
    52     : m_thread(&thread)
     51    : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
    5352    , m_topOrigin(SecurityOrigin::createUnique())
    5453    , m_url(parameters.windowURL)
     
    6362
    6463WorkletGlobalScope::WorkletGlobalScope(Document& document, Ref<JSC::VM>&& vm, ScriptSourceCode&& code)
    65     : WorkerOrWorkletGlobalScope(WTFMove(vm))
     64    : WorkerOrWorkletGlobalScope(WTFMove(vm), nullptr)
    6665    , m_document(makeWeakPtr(document))
    6766    , m_topOrigin(SecurityOrigin::createUnique())
     
    8988void WorkletGlobalScope::prepareForDestruction()
    9089{
    91     if (!script())
    92         return;
    93     if (m_defaultTaskGroup)
    94         m_defaultTaskGroup->stopAndDiscardAllTasks();
    95     stopActiveDOMObjects();
    96     removeAllEventListeners();
    97     if (m_eventLoop)
    98         m_eventLoop->clearMicrotaskQueue();
    99     removeRejectedPromiseTracker();
    100     script()->vm().notifyNeedTermination();
    101     clearScript();
     90    WorkerOrWorkletGlobalScope::prepareForDestruction();
     91
     92    if (script()) {
     93        script()->vm().notifyNeedTermination();
     94        clearScript();
     95    }
    10296}
    10397
     
    106100    static NeverDestroyed<WorkletGlobalScopesSet> scopes;
    107101    return scopes;
    108 }
    109 
    110 EventLoopTaskGroup& WorkletGlobalScope::eventLoop()
    111 {
    112     if (UNLIKELY(!m_defaultTaskGroup)) {
    113         m_eventLoop = WorkerEventLoop::create(*this);
    114         m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
    115         if (activeDOMObjectsAreStopped())
    116             m_defaultTaskGroup->stopAndDiscardAllTasks();
    117     }
    118     return *m_defaultTaskGroup;
    119102}
    120103
     
    130113    if (m_code)
    131114        script()->evaluate(*m_code);
    132 }
    133 
    134 bool WorkletGlobalScope::isJSExecutionForbidden() const
    135 {
    136     return !script() || script()->isExecutionForbidden();
    137 }
    138 
    139 void WorkletGlobalScope::disableEval(const String& errorMessage)
    140 {
    141     script()->disableEval(errorMessage);
    142 }
    143 
    144 void WorkletGlobalScope::disableWebAssembly(const String& errorMessage)
    145 {
    146     script()->disableWebAssembly(errorMessage);
    147115}
    148116
     
    258226}
    259227
    260 bool WorkletGlobalScope::isContextThread() const
    261 {
    262     if (m_thread)
    263         return m_thread->thread() == &Thread::current();
    264     return isMainThread();
    265 }
    266 
    267228} // namespace WebCore
  • trunk/Source/WebCore/worklets/WorkletGlobalScope.h

    r268775 r268822  
    2828
    2929#include "Document.h"
    30 #include "EventTarget.h"
    3130#include "ExceptionOr.h"
    3231#include "FetchRequestCredentials.h"
    3332#include "ScriptExecutionContext.h"
    3433#include "ScriptSourceCode.h"
    35 #include "WorkerEventLoop.h"
    3634#include "WorkerOrWorkletGlobalScope.h"
    3735#include "WorkerOrWorkletScriptController.h"
     
    4846namespace WebCore {
    4947
    50 class EventLoopTaskGroup;
    5148class MessagePortChannelProvider;
    52 class WorkerEventLoop;
    5349class WorkerMessagePortChannelProvider;
    5450class WorkerScriptLoader;
     
    5955using WorkletGlobalScopeIdentifier = ObjectIdentifier<WorkletGlobalScopeIdentifierType>;
    6056
    61 class WorkletGlobalScope : public RefCounted<WorkletGlobalScope>, public EventTargetWithInlineData, public WorkerOrWorkletGlobalScope, public WorkerScriptLoaderClient {
     57class WorkletGlobalScope : public WorkerOrWorkletGlobalScope, public WorkerScriptLoaderClient {
    6258    WTF_MAKE_ISO_ALLOCATED(WorkletGlobalScope);
    6359public:
     
    7672    MessagePortChannelProvider& messagePortChannelProvider();
    7773
    78     EventLoopTaskGroup& eventLoop() final;
    79 
    8074    const URL& url() const final { return m_url; }
    8175
     
    8478    ReferrerPolicy referrerPolicy() const final;
    8579
    86     using RefCounted::ref;
    87     using RefCounted::deref;
    88 
    89     WorkerOrWorkletThread* workerOrWorkletThread() const final { return m_thread.get(); }
    90 
    9180    void addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&&) final;
    9281
    93     bool isJSExecutionForbidden() const final;
    9482    SecurityOrigin& topOrigin() const final { return m_topOrigin.get(); }
    9583
    9684    SocketProvider* socketProvider() final { return nullptr; }
    9785
    98     // WorkerOrWorkletGlobalScope.
    99     bool isClosing() const final { return m_isClosing; }
    100 
    101     bool isContextThread() const final;
    10286    bool isSecureContext() const final { return false; }
    10387
    10488    JSC::RuntimeFlags jsRuntimeFlags() const { return m_jsRuntimeFlags; }
    10589
    106     virtual void prepareForDestruction();
     90    void prepareForDestruction() override;
    10791
    10892    void fetchAndInvokeScript(const URL&, FetchRequestCredentials, CompletionHandler<void(Optional<Exception>&&)>&&);
     
    11498    WorkletGlobalScope(WorkerOrWorkletThread&, const WorkletParameters&);
    11599    WorkletGlobalScope(Document&, Ref<JSC::VM>&&, ScriptSourceCode&&);
    116     WorkletGlobalScope(const WorkletGlobalScope&) = delete;
    117     WorkletGlobalScope(WorkletGlobalScope&&) = delete;
    118 
    119     WorkerEventLoop* existingEventLoop() const { return m_eventLoop.get(); }
    120     EventLoopTaskGroup* defaultTaskGroup() const { return m_defaultTaskGroup.get(); }
    121100
    122101private:
     
    125104#endif
    126105
    127     void postTask(Task&&) override { ASSERT_NOT_REACHED(); }
    128 
    129     void refScriptExecutionContext() final { ref(); }
    130     void derefScriptExecutionContext() final { deref(); }
    131 
    132     void refEventTarget() final { ref(); }
    133     void derefEventTarget() final { deref(); }
    134 
    135     ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkletGlobalScope*>(this); }
     106    // EventTarget.
    136107    EventTargetInterface eventTargetInterface() const final { return WorkletGlobalScopeEventTargetInterfaceType; }
    137108
     
    154125    URL completeURL(const String&, ForceUTF8 = ForceUTF8::No) const final;
    155126    String userAgent(const URL&) const final;
    156     void disableEval(const String&) final;
    157     void disableWebAssembly(const String&) final;
    158127
    159128    struct ScriptFetchJob {
     
    167136
    168137    WeakPtr<Document> m_document;
    169     RefPtr<WorkerOrWorkletThread> m_thread;
    170138
    171139    Ref<SecurityOrigin> m_topOrigin;
    172 
    173     RefPtr<WorkerEventLoop> m_eventLoop;
    174     std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
    175140
    176141    URL m_url;
     
    183148    Deque<ScriptFetchJob> m_scriptFetchJobs;
    184149    HashSet<URL> m_evaluatedModules;
    185 
    186     bool m_isClosing { false };
    187150};
    188151
Note: See TracChangeset for help on using the changeset viewer.