Changeset 252607 in webkit


Ignore:
Timestamp:
Nov 18, 2019 4:54:57 PM (4 years ago)
Author:
rniwa@webkit.org
Message:

Share more code between WindowEventLoop and WorkerEventLoop by introducing EventLoopTaskGroup
https://bugs.webkit.org/show_bug.cgi?id=204263

Reviewed by Antti Koivisto.

This patch abstracts the logic in WindowEventLoop to deal with a set of tasks associated with
a particular documents all suspending, resuming, or stopping at the same time using a new abstraction
called EventLoopTaskGroup in order to group tasks for media code and elsewhere.

Each task is now represented as an instance of a concrete subclass of EventLoopTask, which has
a pure virtual execute() member function. Its primary purpose is to know EventLoopTaskGroup to which
each task belongs. One of subclasss, EventLoopFunctionDispatchTask, is used to store a callback function
and another subclass, ActiveDOMObjectEventDispatchTask, is used to dispatch an async event.

ScriptExecutionContext's eventLoop() method now returns EventLoopTaskGroup. Because this group is
specific to a given ScriptExecutionContext, we no longer have to pass the ScriptExecutionContext
in each call to queueTask everywhere in our codebase.

For now, I kept all the code in WindowEventLoop.cpp to make the patch reviewable. My plan is to create
a new cpp file (e.g. AbstractEventLoop.cpp) and move most of code there instead as a follow up.

No new tests since there should be no observable behavior change.

  • Modules/encryptedmedia/MediaKeys.cpp:

(WebCore::MediaKeys::setServerCertificate):

  • Modules/entriesapi/FileSystemDirectoryEntry.cpp:

(WebCore::FileSystemDirectoryEntry::getEntry):

  • Modules/entriesapi/FileSystemDirectoryReader.cpp:

(WebCore::FileSystemDirectoryReader::readEntries):

  • Modules/entriesapi/FileSystemEntry.cpp:

(WebCore::FileSystemEntry::getParent):

  • Modules/entriesapi/FileSystemFileEntry.cpp:

(WebCore::FileSystemFileEntry::file):

  • Modules/mediarecorder/MediaRecorder.cpp:

(WebCore::MediaRecorder::scheduleDeferredTask):

  • Modules/notifications/Notification.cpp:

(WebCore::Notification::queueTask):

  • Modules/webdatabase/Database.cpp:

(WebCore::Database::runTransaction):

  • Modules/webdatabase/DatabaseManager.cpp:

(WebCore::DatabaseManager::openDatabase):

  • Modules/webdatabase/SQLTransaction.cpp:

(WebCore::SQLTransaction::callErrorCallbackDueToInterruption):
(WebCore::SQLTransaction::deliverTransactionErrorCallback):
(WebCore::SQLTransaction::deliverSuccessCallback):

  • bindings/js/JSDOMPromiseDeferred.cpp:

(WebCore::DeferredPromise::callFunction):
(WebCore::DeferredPromise::whenSettled):

  • dom/AbstractEventLoop.h:

(WebCore::EventLoopTask): Added.
(WebCore::EventLoopTask::taskSource): Added.
(WebCore::EventLoopTask::group const): Added.
(WebCore::EventLoopTask::EventLoopTask): Added.
(WebCore::EventLoopTaskGroup): Added. This class represents a group of tasks. For now, each group is
a distinct ScriptExecutionContext.
(WebCore::EventLoopTaskGroup::matchesTask const): Added.
(WebCore::EventLoopTaskGroup::startRunning): Added.
(WebCore::EventLoopTaskGroup::stopAndDiscardAllTasks): Added.
(WebCore::EventLoopTaskGroup::suspend): Added.
(WebCore::EventLoopTaskGroup::resume): Added.
(WebCore::EventLoopTaskGroup::isStoppedPermanently): Added.
(WebCore::EventLoopTaskGroup::isSuspended): Added.
(WebCore::EventLoopTaskGroup::hasScheduledTasks const): Added.
(WebCore::EventLoopTaskGroup::queueTask): Added.

  • dom/ActiveDOMObject.cpp:

(WebCore::ActiveDOMObject::queueTaskInEventLoop):
(WebCore::ActiveDOMObjectEventDispatchTask): Added; A subclass of EventLoopTask to dispatch an async event.
(WebCore::ActiveDOMObjectEventDispatchTask::ActiveDOMObjectEventDispatchTask): Added.
(WebCore::ActiveDOMObjectEventDispatchTask::~ActiveDOMObjectEventDispatchTask): Added.
(WebCore::ActiveDOMObject::queueTaskToDispatchEventInternal): Added.

  • dom/ActiveDOMObject.h:
  • dom/Document.cpp:

(WebCore::Document::suspendActiveDOMObjects):
(WebCore::Document::resumeActiveDOMObjects):
(WebCore::Document::stopActiveDOMObjects):
(WebCore::Document::eventLoop): Creates EventLoopTaskGroup for this document.

  • dom/Document.h:
  • dom/IdleCallbackController.cpp:

(WebCore::IdleCallbackController::queueTaskToStartIdlePeriod):
(WebCore::IdleCallbackController::queueTaskToInvokeIdleCallbacks):

  • dom/ScriptExecutionContext.h:
  • dom/WindowEventLoop.cpp:

(WebCore::AbstractEventLoop::queueTask): The implementation moved from WindowEventLoop to AbstractEventLoop.
(WebCore::AbstractEventLoop::suspend): Removed.
(WebCore::AbstractEventLoop::resumeGroup): Ditto.
(WebCore::AbstractEventLoop::stopGroup): Ditto.
(WebCore::WindowEventLoop::scheduleToRun): Renamed from WindowEventLoop::scheduleToRunIfNeeded.
(WebCore::AbstractEventLoop::scheduleToRunIfNeeded): Extracted from WindowEventLoop::scheduleToRunIfNeeded.
(WebCore::WindowEventLoop::isContextThread const): Added.
(WebCore::AbstractEventLoop::run): The implementation moved from WindowEventLoop to AbstractEventLoop.
(WebCore::AbstractEventLoop::clearAllTasks): Added.
(WebCore::EventLoopFunctionDispatchTask): Added; A subclass of EventLoopTask to call a function.
(WebCore::EventLoopFunctionDispatchTask::EventLoopFunctionDispatchTask): Added.
(WebCore::EventLoopTaskGroup::queueTask): Added.

  • dom/WindowEventLoop.h:
  • fileapi/FileReader.cpp:

(WebCore::FileReader::enqueueTask):

  • testing/Internals.cpp:

(WebCore::Internals::queueTask):

  • workers/WorkerEventLoop.cpp:

(WebCore::WorkerEventLoop::WorkerEventLoop):
(WebCore::WorkerEventLoop::queueTask): Deleted.
(WebCore::WorkerEventLoop::activeDOMObjectName const): Deleted.
(WebCore::WorkerEventLoop::suspend): Deleted.
(WebCore::WorkerEventLoop::resume): Deleted.
(WebCore::WorkerEventLoop::stop): Deleted.
(WebCore::WorkerEventLoop::scheduleToRun): Extracted from scheduleToRunIfNeeded.
(WebCore::WorkerEventLoop::scheduleToRunIfNeeded): Deleted.
(WebCore::WorkerEventLoop::run): Deleted.
(WebCore::WorkerEventLoop::isContextThread const): Added.

  • workers/WorkerEventLoop.h:

(WebCore::WorkerEventLoop): This class is no longer an active DOM object. WorkerGlobalScope and WorkerGlobalScope
manually stop the task group associated with it.

  • workers/WorkerGlobalScope.cpp:

(WebCore::WorkerGlobalScope::eventLoop): Create the default task group for this script execution context.
(WebCore::WorkerGlobalScope::prepareForTermination): Stop the default task group.

  • workers/WorkerGlobalScope.h:
  • worklets/WorkletGlobalScope.cpp:

(WebCore::WorkletGlobalScope::prepareForDestruction): Similar to WorkerGlobalScope::prepareForTermination.
(WebCore::WorkletGlobalScope::eventLoop): Similar to WorkerGlobalScope::eventLoop.

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

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r252599 r252607  
     12019-11-15  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Share more code between WindowEventLoop and WorkerEventLoop by introducing EventLoopTaskGroup
     4        https://bugs.webkit.org/show_bug.cgi?id=204263
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This patch abstracts the logic in WindowEventLoop to deal with a set of tasks associated with
     9        a particular documents all suspending, resuming, or stopping at the same time using a new abstraction
     10        called EventLoopTaskGroup in order to group tasks for media code and elsewhere.
     11
     12        Each task is now represented as an instance of a concrete subclass of EventLoopTask, which has
     13        a pure virtual execute() member function. Its primary purpose is to know EventLoopTaskGroup to which
     14        each task belongs. One of subclasss, EventLoopFunctionDispatchTask, is used to store a callback function
     15        and another subclass, ActiveDOMObjectEventDispatchTask, is used to dispatch an async event.
     16
     17        ScriptExecutionContext's eventLoop() method now returns EventLoopTaskGroup. Because this group is
     18        specific to a given ScriptExecutionContext, we no longer have to pass the ScriptExecutionContext
     19        in each call to queueTask everywhere in our codebase.
     20
     21        For now, I kept all the code in WindowEventLoop.cpp to make the patch reviewable. My plan is to create
     22        a new cpp file (e.g. AbstractEventLoop.cpp) and move most of code there instead as a follow up.
     23
     24        No new tests since there should be no observable behavior change.
     25
     26        * Modules/encryptedmedia/MediaKeys.cpp:
     27        (WebCore::MediaKeys::setServerCertificate):
     28        * Modules/entriesapi/FileSystemDirectoryEntry.cpp:
     29        (WebCore::FileSystemDirectoryEntry::getEntry):
     30        * Modules/entriesapi/FileSystemDirectoryReader.cpp:
     31        (WebCore::FileSystemDirectoryReader::readEntries):
     32        * Modules/entriesapi/FileSystemEntry.cpp:
     33        (WebCore::FileSystemEntry::getParent):
     34        * Modules/entriesapi/FileSystemFileEntry.cpp:
     35        (WebCore::FileSystemFileEntry::file):
     36        * Modules/mediarecorder/MediaRecorder.cpp:
     37        (WebCore::MediaRecorder::scheduleDeferredTask):
     38        * Modules/notifications/Notification.cpp:
     39        (WebCore::Notification::queueTask):
     40        * Modules/webdatabase/Database.cpp:
     41        (WebCore::Database::runTransaction):
     42        * Modules/webdatabase/DatabaseManager.cpp:
     43        (WebCore::DatabaseManager::openDatabase):
     44        * Modules/webdatabase/SQLTransaction.cpp:
     45        (WebCore::SQLTransaction::callErrorCallbackDueToInterruption):
     46        (WebCore::SQLTransaction::deliverTransactionErrorCallback):
     47        (WebCore::SQLTransaction::deliverSuccessCallback):
     48        * bindings/js/JSDOMPromiseDeferred.cpp:
     49        (WebCore::DeferredPromise::callFunction):
     50        (WebCore::DeferredPromise::whenSettled):
     51        * dom/AbstractEventLoop.h:
     52        (WebCore::EventLoopTask): Added.
     53        (WebCore::EventLoopTask::taskSource): Added.
     54        (WebCore::EventLoopTask::group const): Added.
     55        (WebCore::EventLoopTask::EventLoopTask): Added.
     56        (WebCore::EventLoopTaskGroup): Added. This class represents a group of tasks. For now, each group is
     57        a distinct ScriptExecutionContext.
     58        (WebCore::EventLoopTaskGroup::matchesTask const): Added.
     59        (WebCore::EventLoopTaskGroup::startRunning): Added.
     60        (WebCore::EventLoopTaskGroup::stopAndDiscardAllTasks): Added.
     61        (WebCore::EventLoopTaskGroup::suspend): Added.
     62        (WebCore::EventLoopTaskGroup::resume): Added.
     63        (WebCore::EventLoopTaskGroup::isStoppedPermanently): Added.
     64        (WebCore::EventLoopTaskGroup::isSuspended): Added.
     65        (WebCore::EventLoopTaskGroup::hasScheduledTasks const): Added.
     66        (WebCore::EventLoopTaskGroup::queueTask): Added.
     67        * dom/ActiveDOMObject.cpp:
     68        (WebCore::ActiveDOMObject::queueTaskInEventLoop):
     69        (WebCore::ActiveDOMObjectEventDispatchTask): Added; A subclass of EventLoopTask to dispatch an async event.
     70        (WebCore::ActiveDOMObjectEventDispatchTask::ActiveDOMObjectEventDispatchTask): Added.
     71        (WebCore::ActiveDOMObjectEventDispatchTask::~ActiveDOMObjectEventDispatchTask): Added.
     72        (WebCore::ActiveDOMObject::queueTaskToDispatchEventInternal): Added.
     73        * dom/ActiveDOMObject.h:
     74        * dom/Document.cpp:
     75        (WebCore::Document::suspendActiveDOMObjects):
     76        (WebCore::Document::resumeActiveDOMObjects):
     77        (WebCore::Document::stopActiveDOMObjects):
     78        (WebCore::Document::eventLoop): Creates EventLoopTaskGroup for this document.
     79        * dom/Document.h:
     80        * dom/IdleCallbackController.cpp:
     81        (WebCore::IdleCallbackController::queueTaskToStartIdlePeriod):
     82        (WebCore::IdleCallbackController::queueTaskToInvokeIdleCallbacks):
     83        * dom/ScriptExecutionContext.h:
     84        * dom/WindowEventLoop.cpp:
     85        (WebCore::AbstractEventLoop::queueTask): The implementation moved from WindowEventLoop to AbstractEventLoop.
     86        (WebCore::AbstractEventLoop::suspend): Removed.
     87        (WebCore::AbstractEventLoop::resumeGroup): Ditto.
     88        (WebCore::AbstractEventLoop::stopGroup): Ditto.
     89        (WebCore::WindowEventLoop::scheduleToRun): Renamed from WindowEventLoop::scheduleToRunIfNeeded.
     90        (WebCore::AbstractEventLoop::scheduleToRunIfNeeded): Extracted from WindowEventLoop::scheduleToRunIfNeeded.
     91        (WebCore::WindowEventLoop::isContextThread const): Added.
     92        (WebCore::AbstractEventLoop::run): The implementation moved from WindowEventLoop to AbstractEventLoop.
     93        (WebCore::AbstractEventLoop::clearAllTasks): Added.
     94        (WebCore::EventLoopFunctionDispatchTask): Added; A subclass of EventLoopTask to call a function.
     95        (WebCore::EventLoopFunctionDispatchTask::EventLoopFunctionDispatchTask): Added.
     96        (WebCore::EventLoopTaskGroup::queueTask): Added.
     97        * dom/WindowEventLoop.h:
     98        * fileapi/FileReader.cpp:
     99        (WebCore::FileReader::enqueueTask):
     100        * testing/Internals.cpp:
     101        (WebCore::Internals::queueTask):
     102        * workers/WorkerEventLoop.cpp:
     103        (WebCore::WorkerEventLoop::WorkerEventLoop):
     104        (WebCore::WorkerEventLoop::queueTask): Deleted.
     105        (WebCore::WorkerEventLoop::activeDOMObjectName const): Deleted.
     106        (WebCore::WorkerEventLoop::suspend): Deleted.
     107        (WebCore::WorkerEventLoop::resume): Deleted.
     108        (WebCore::WorkerEventLoop::stop): Deleted.
     109        (WebCore::WorkerEventLoop::scheduleToRun): Extracted from scheduleToRunIfNeeded.
     110        (WebCore::WorkerEventLoop::scheduleToRunIfNeeded): Deleted.
     111        (WebCore::WorkerEventLoop::run): Deleted.
     112        (WebCore::WorkerEventLoop::isContextThread const): Added.
     113        * workers/WorkerEventLoop.h:
     114        (WebCore::WorkerEventLoop): This class is no longer an active DOM object. WorkerGlobalScope and WorkerGlobalScope
     115        manually stop the task group associated with it.
     116        * workers/WorkerGlobalScope.cpp:
     117        (WebCore::WorkerGlobalScope::eventLoop): Create the default task group for this script execution context.
     118        (WebCore::WorkerGlobalScope::prepareForTermination): Stop the default task group.
     119        * workers/WorkerGlobalScope.h:
     120        * worklets/WorkletGlobalScope.cpp:
     121        (WebCore::WorkletGlobalScope::prepareForDestruction): Similar to WorkerGlobalScope::prepareForTermination.
     122        (WebCore::WorkletGlobalScope::eventLoop): Similar to WorkerGlobalScope::eventLoop.
     123        * worklets/WorkletGlobalScope.h:
     124
    11252019-11-18  Antti Koivisto  <antti@apple.com>
    2126
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp

    r252033 r252607  
    107107    // 5. Run the following steps in parallel:
    108108
    109     context.eventLoop().queueTask(TaskSource::Networking, context, [this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
     109    context.eventLoop().queueTask(TaskSource::Networking, [this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
    110110        // 5.1. Use this object's cdm instance to process certificate.
    111111        if (m_instance->setServerCertificate(WTFMove(certificate)) == CDMInstance::Failed) {
  • trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryEntry.cpp

    r251524 r252607  
    5858        if (result.hasException()) {
    5959            if (errorCallback && document) {
    60                 document->eventLoop().queueTask(TaskSource::Networking, *document, [errorCallback = WTFMove(errorCallback), exception = result.releaseException(), pendingActivity = WTFMove(pendingActivity)]() mutable {
     60                document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), exception = result.releaseException(), pendingActivity = WTFMove(pendingActivity)]() mutable {
    6161                    errorCallback->handleEvent(DOMException::create(WTFMove(exception)));
    6262                });
     
    6767        if (!matches(entry)) {
    6868            if (errorCallback && document) {
    69                 document->eventLoop().queueTask(TaskSource::Networking, *document, [errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
     69                document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
    7070                    errorCallback->handleEvent(DOMException::create(Exception { TypeMismatchError, "Entry at given path does not match expected type"_s }));
    7171                });
     
    7474        }
    7575        if (successCallback && document) {
    76             document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), entry = WTFMove(entry), pendingActivity = WTFMove(pendingActivity)]() mutable {
     76            document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), entry = WTFMove(entry), pendingActivity = WTFMove(pendingActivity)]() mutable {
    7777                successCallback->handleEvent(WTFMove(entry));
    7878            });
  • trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryReader.cpp

    r251509 r252607  
    9090                m_error = result.releaseException();
    9191                if (errorCallback && document) {
    92                     document->eventLoop().queueTask(TaskSource::Networking, *document, [this, errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
     92                    document->eventLoop().queueTask(TaskSource::Networking, [this, errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
    9393                        errorCallback->handleEvent(DOMException::create(*m_error));
    9494                    });
     
    9898            m_isDone = true;
    9999            if (document) {
    100                 document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), pendingActivity = WTFMove(pendingActivity), result = result.releaseReturnValue()]() mutable {
     100                document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), pendingActivity = WTFMove(pendingActivity), result = result.releaseReturnValue()]() mutable {
    101101                    successCallback->handleEvent(WTFMove(result));
    102102                });
  • trunk/Source/WebCore/Modules/entriesapi/FileSystemEntry.cpp

    r251690 r252607  
    7878            return;
    7979
    80         document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
     80        document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
    8181            if (result.hasException()) {
    8282                if (errorCallback)
  • trunk/Source/WebCore/Modules/entriesapi/FileSystemFileEntry.cpp

    r251690 r252607  
    4949            return;
    5050
    51         document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
     51        document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
    5252            if (result.hasException()) {
    5353                if (errorCallback)
  • trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp

    r252003 r252607  
    217217        return;
    218218
    219     document->eventLoop().queueTask(TaskSource::Networking, *document, [pendingActivity = makePendingActivity(*this), function = WTFMove(function)] {
     219    document->eventLoop().queueTask(TaskSource::Networking, [pendingActivity = makePendingActivity(*this), function = WTFMove(function)] {
    220220        function();
    221221    });
  • trunk/Source/WebCore/Modules/notifications/Notification.cpp

    r251528 r252607  
    153153        return;
    154154
    155     document->eventLoop().queueTask(TaskSource::UserInteraction, *document, WTFMove(task));
     155    document->eventLoop().queueTask(TaskSource::UserInteraction, WTFMove(task));
    156156}
    157157
  • trunk/Source/WebCore/Modules/webdatabase/Database.cpp

    r252064 r252607  
    690690    if (!m_isTransactionQueueEnabled) {
    691691        if (errorCallback) {
    692             m_document->eventLoop().queueTask(TaskSource::Networking, m_document, [errorCallback = makeRef(*errorCallback)]() {
     692            m_document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = makeRef(*errorCallback)]() {
    693693                errorCallback->handleEvent(SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed"));
    694694            });
  • trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp

    r252064 r252607  
    211211        LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database.get());
    212212        database->setHasPendingCreationEvent(true);
    213         database->m_document->eventLoop().queueTask(TaskSource::Networking, database->m_document, [creationCallback, database]() {
     213        database->m_document->eventLoop().queueTask(TaskSource::Networking, [creationCallback, database]() {
    214214            creationCallback->handleEvent(*database);
    215215            database->setHasPendingCreationEvent(false);
  • trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp

    r252064 r252607  
    142142        return;
    143143
    144     m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [errorCallback = WTFMove(errorCallback)]() mutable {
     144    m_database->document().eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback)]() mutable {
    145145        errorCallback->handleEvent(SQLError::create(SQLError::DATABASE_ERR, "the database was closed"));
    146146    });
     
    416416    RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap();
    417417    if (errorCallback) {
    418         m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [errorCallback = WTFMove(errorCallback), transactionError = m_transactionError]() mutable {
     418        m_database->document().eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), transactionError = m_transactionError]() mutable {
    419419            errorCallback->handleEvent(*transactionError);
    420420        });
     
    467467    RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap();
    468468    if (successCallback) {
    469         m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [successCallback = WTFMove(successCallback)]() mutable {
     469        m_database->document().eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback)]() mutable {
    470470            successCallback->handleEvent();
    471471        });
  • trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp

    r252338 r252607  
    5252    if (activeDOMObjectsAreSuspended()) {
    5353        JSC::Strong<JSC::Unknown, ShouldStrongDestructorGrabLock::Yes> strongResolution(lexicalGlobalObject.vm(), resolution);
    54         scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, *scriptExecutionContext(), [this, protectedThis = makeRef(*this), mode, strongResolution = WTFMove(strongResolution)]() mutable {
     54        scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = makeRef(*this), mode, strongResolution = WTFMove(strongResolution)]() mutable {
    5555            if (shouldIgnoreRequestToFulfill())
    5656                return;
     
    8484
    8585    if (activeDOMObjectsAreSuspended()) {
    86         scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, *scriptExecutionContext(), [this, protectedThis = makeRef(*this), callback = WTFMove(callback)]() mutable {
     86        scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = makeRef(*this), callback = WTFMove(callback)]() mutable {
    8787            whenSettled(WTFMove(callback));
    8888        });
  • trunk/Source/WebCore/dom/AbstractEventLoop.h

    r251975 r252607  
    2929#include <wtf/Function.h>
    3030#include <wtf/RefCounted.h>
     31#include <wtf/StdLibExtras.h>
     32#include <wtf/WeakHashSet.h>
     33#include <wtf/WeakPtr.h>
    3134
    3235namespace WebCore {
    3336
     37class EventLoopTaskGroup;
     38class EventTarget;
    3439class ScriptExecutionContext;
    3540
     41class EventLoopTask {
     42    WTF_MAKE_NONCOPYABLE(EventLoopTask);
     43    WTF_MAKE_FAST_ALLOCATED;
     44
     45public:
     46    virtual ~EventLoopTask() = default;
     47
     48    TaskSource taskSource() { return m_taskSource; }
     49    virtual void execute() = 0;
     50
     51    EventLoopTaskGroup* group() const { return m_group.get(); }
     52
     53protected:
     54    EventLoopTask(TaskSource, EventLoopTaskGroup&);
     55
     56private:
     57    const TaskSource m_taskSource;
     58    WeakPtr<EventLoopTaskGroup> m_group;
     59};
     60
    3661// https://html.spec.whatwg.org/multipage/webappapis.html#event-loop
    37 class AbstractEventLoop : public RefCounted<AbstractEventLoop> {
     62class AbstractEventLoop : public RefCounted<AbstractEventLoop>, public CanMakeWeakPtr<AbstractEventLoop> {
    3863public:
    3964    virtual ~AbstractEventLoop() = default;
    4065
    41     typedef WTF::Function<void ()> TaskFunction;
    42     virtual void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) = 0;
     66    typedef Function<void ()> TaskFunction;
     67    void queueTask(std::unique_ptr<EventLoopTask>&&);
     68
     69    void resumeGroup(EventLoopTaskGroup&);
     70    void stopGroup(EventLoopTaskGroup&);
    4371
    4472protected:
    4573    AbstractEventLoop() = default;
     74    void run();
     75    void clearAllTasks();
     76
     77private:
     78    void scheduleToRunIfNeeded();
     79    virtual void scheduleToRun() = 0;
     80    virtual bool isContextThread() const = 0;
     81
     82    // Use a global queue instead of multiple task queues since HTML5 spec allows UA to pick arbitrary queue.
     83    Vector<std::unique_ptr<EventLoopTask>> m_tasks;
     84    WeakHashSet<EventLoopTaskGroup> m_groupsWithSuspenedTasks;
     85    bool m_isScheduledToRun { false };
    4686};
    4787
     88class EventLoopTaskGroup : public CanMakeWeakPtr<EventLoopTaskGroup> {
     89    WTF_MAKE_NONCOPYABLE(EventLoopTaskGroup);
     90    WTF_MAKE_FAST_ALLOCATED;
     91
     92public:
     93    EventLoopTaskGroup(AbstractEventLoop& eventLoop)
     94        : m_eventLoop(makeWeakPtr(eventLoop))
     95    {
     96    }
     97
     98    bool matchesTask(EventLoopTask& task) const
     99    {
     100        auto* group = task.group();
     101        return group == this;
     102    }
     103
     104    void stopAndDiscardAllTasks()
     105    {
     106        m_state = State::Stopped;
     107        if (auto* eventLoop = m_eventLoop.get())
     108            eventLoop->stopGroup(*this);
     109    }
     110
     111    void suspend()
     112    {
     113        ASSERT(m_state != State::Stopped);
     114        m_state = State::Suspended;
     115        // We don't remove suspended tasks to preserve the ordering.
     116        // AbstractEventLoop::run checks whether each task's group is suspended or not.
     117    }
     118
     119    void resume()
     120    {
     121        ASSERT(m_state != State::Stopped);
     122        m_state = State::Running;
     123        if (auto* eventLoop = m_eventLoop.get())
     124            eventLoop->resumeGroup(*this);
     125    }
     126
     127    bool isStoppedPermanently() { return m_state == State::Stopped; }
     128    bool isSuspended() { return m_state == State::Suspended; }
     129
     130    void queueTask(std::unique_ptr<EventLoopTask>&& task)
     131    {
     132        if (m_state == State::Stopped || !m_eventLoop)
     133            return;
     134        ASSERT(task->group() == this);
     135        m_eventLoop->queueTask(WTFMove(task));
     136    }
     137
     138    WEBCORE_EXPORT void queueTask(TaskSource, AbstractEventLoop::TaskFunction&&);
     139
     140private:
     141    enum class State : uint8_t { Running, Suspended, Stopped };
     142
     143    WeakPtr<AbstractEventLoop> m_eventLoop;
     144    State m_state { State::Running };
     145};
     146
     147inline EventLoopTask::EventLoopTask(TaskSource source, EventLoopTaskGroup& group)
     148    : m_taskSource(source)
     149    , m_group(makeWeakPtr(group))
     150{ }
     151
    48152} // namespace WebCore
  • trunk/Source/WebCore/dom/ActiveDOMObject.cpp

    r252545 r252607  
    136136}
    137137
    138 void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void ()>&& task)
     138void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void ()>&& function)
    139139{
    140140    auto* context = scriptExecutionContext();
    141141    if (!context)
    142142        return;
    143     context->eventLoop().queueTask(source, *context, WTFMove(task));
     143    context->eventLoop().queueTask(source, WTFMove(function));
     144}
     145
     146class ActiveDOMObjectEventDispatchTask : public EventLoopTask {
     147public:
     148    ActiveDOMObjectEventDispatchTask(TaskSource source, EventLoopTaskGroup& group, ActiveDOMObject& object, EventTarget& target, Ref<Event>&& event)
     149        : EventLoopTask(source, group)
     150        , m_object(object)
     151        , m_target(target)
     152        , m_event(WTFMove(event))
     153    {
     154        ++m_object.m_pendingActivityCount;
     155    }
     156
     157    ~ActiveDOMObjectEventDispatchTask()
     158    {
     159        ASSERT(m_object.m_pendingActivityCount);
     160        --m_object.m_pendingActivityCount;
     161    }
     162
     163    void execute() final { m_target->dispatchEvent(m_event.get()); }
     164
     165private:
     166    ActiveDOMObject& m_object;
     167    Ref<EventTarget> m_target;
     168    Ref<Event> m_event;
     169};
     170
     171void ActiveDOMObject::queueTaskToDispatchEventInternal(EventTarget& target, TaskSource source, Ref<Event>&& event)
     172{
     173    ASSERT(!event->target() || &target == event->target());
     174    auto* context = scriptExecutionContext();
     175    if (!context)
     176        return;
     177    auto& eventLoopTaskGroup = context->eventLoop();
     178    auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, target, WTFMove(event));
     179    eventLoopTaskGroup.queueTask(WTFMove(task));
    144180}
    145181
  • trunk/Source/WebCore/dom/ActiveDOMObject.h

    r252212 r252607  
    3838
    3939class Document;
     40class Event;
     41class EventLoopTaskGroup;
     42class EventTarget;
    4043
    4144enum class ReasonForSuspension {
     
    117120    static void queueTaskKeepingObjectAlive(T& object, TaskSource source, Function<void ()>&& task)
    118121    {
    119         object.queueTaskInEventLoop(source, [protectedObject = makeRef(object), activity = object.makePendingActivity(object), task = WTFMove(task)] () {
     122        object.queueTaskInEventLoop(source, [protectedObject = makeRef(object), activity = object.ActiveDOMObject::makePendingActivity(object), task = WTFMove(task)] () {
    120123            task();
    121124        });
     
    125128    static void queueTaskToDispatchEvent(EventTargetType& target, TaskSource source, Ref<EventType>&& event)
    126129    {
    127         ASSERT(!event->target() || &target == event->target());
    128         queueTaskKeepingObjectAlive(target, source, [&target, event = WTFMove(event)] () mutable {
    129             target.dispatchEvent(event.get());
    130         });
     130        target.queueTaskToDispatchEventInternal(target, source, WTFMove(event));
    131131    }
    132132
     
    142142
    143143    void queueTaskInEventLoop(TaskSource, Function<void ()>&&);
     144    void queueTaskToDispatchEventInternal(EventTarget&, TaskSource, Ref<Event>&&);
    144145
    145146    unsigned m_pendingActivityCount { 0 };
     
    148149    Ref<Thread> m_creationThread { Thread::current() };
    149150#endif
     151
     152    friend class ActiveDOMObjectEventDispatchTask;
    150153};
    151154
  • trunk/Source/WebCore/dom/Document.cpp

    r252546 r252607  
    26472647void Document::suspendActiveDOMObjects(ReasonForSuspension why)
    26482648{
    2649     if (m_eventLoop)
    2650         m_eventLoop->suspend(*this);
     2649    if (m_documentTaskGroup)
     2650        m_documentTaskGroup->suspend();
    26512651    ScriptExecutionContext::suspendActiveDOMObjects(why);
    26522652    suspendDeviceMotionAndOrientationUpdates();
     
    26562656void Document::resumeActiveDOMObjects(ReasonForSuspension why)
    26572657{
    2658     if (m_eventLoop)
    2659         m_eventLoop->resume(*this);
     2658    if (m_documentTaskGroup)
     2659        m_documentTaskGroup->resume();
    26602660    ScriptExecutionContext::resumeActiveDOMObjects(why);
    26612661    resumeDeviceMotionAndOrientationUpdates();
     
    26652665void Document::stopActiveDOMObjects()
    26662666{
    2667     if (m_eventLoop)
    2668         m_eventLoop->stop(*this);
     2667    if (m_documentTaskGroup)
     2668        m_documentTaskGroup->stopAndDiscardAllTasks();
    26692669    ScriptExecutionContext::stopActiveDOMObjects();
    26702670    platformSuspendOrStopActiveDOMObjects();
     
    62446244}
    62456245
    6246 AbstractEventLoop& Document::eventLoop()
     6246EventLoopTaskGroup& Document::eventLoop()
    62476247{
    62486248    ASSERT(isMainThread());
    6249     if (UNLIKELY(!m_eventLoop))
     6249    if (UNLIKELY(!m_documentTaskGroup)) {
    62506250        m_eventLoop = WindowEventLoop::ensureForRegistrableDomain(RegistrableDomain { securityOrigin().data() });
    6251     return *m_eventLoop;
     6251        m_documentTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
     6252        if (activeDOMObjectsAreStopped())
     6253            m_documentTaskGroup->stopAndDiscardAllTasks();
     6254        else if (activeDOMObjectsAreSuspended())
     6255            m_documentTaskGroup->suspend();
     6256    }
     6257    return *m_documentTaskGroup;
    62526258}
    62536259
  • trunk/Source/WebCore/dom/Document.h

    r252546 r252607  
    122122class DocumentType;
    123123class EditingBehavior;
     124class EventLoopTaskGroup;
    124125class ExtensionStyleSheets;
    125126class FloatQuad;
     
    10641065    WEBCORE_EXPORT void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
    10651066
    1066     AbstractEventLoop& eventLoop() final;
     1067    EventLoopTaskGroup& eventLoop() final;
    10671068
    10681069    ScriptedAnimationController* scriptedAnimationController() { return m_scriptedAnimationController.get(); }
     
    20652066
    20662067    RefPtr<WindowEventLoop> m_eventLoop;
     2068    std::unique_ptr<EventLoopTaskGroup> m_documentTaskGroup;
    20672069
    20682070#if ENABLE(SERVICE_WORKER)
  • trunk/Source/WebCore/dom/IdleCallbackController.cpp

    r251050 r252607  
    7272void IdleCallbackController::queueTaskToStartIdlePeriod()
    7373{
    74     m_document->eventLoop().queueTask(TaskSource::IdleTask, *m_document, [protectedDocument = makeRef(*m_document), this]() {
     74    m_document->eventLoop().queueTask(TaskSource::IdleTask, [protectedDocument = makeRef(*m_document), this] {
    7575        RELEASE_ASSERT(protectedDocument->idleCallbackController() == this);
    7676        startIdlePeriod();
     
    101101void IdleCallbackController::queueTaskToInvokeIdleCallbacks(MonotonicTime deadline)
    102102{
    103     m_document->eventLoop().queueTask(TaskSource::IdleTask, *m_document, [protectedDocument = makeRef(*m_document), deadline, this]() {
     103    m_document->eventLoop().queueTask(TaskSource::IdleTask, [protectedDocument = makeRef(*m_document), deadline, this] {
    104104        RELEASE_ASSERT(protectedDocument->idleCallbackController() == this);
    105105        invokeIdleCallbacks(deadline);
  • trunk/Source/WebCore/dom/ScriptExecutionContext.h

    r252263 r252607  
    5858class DatabaseContext;
    5959class EventQueue;
     60class EventLoopTaskGroup;
    6061class EventTarget;
    6162class MessagePort;
     
    6566class SecurityOrigin;
    6667class SocketProvider;
     68enum class TaskSource : uint8_t;
    6769
    6870#if ENABLE(SERVICE_WORKER)
     
    9092    virtual bool isJSExecutionForbidden() const = 0;
    9193
    92     virtual AbstractEventLoop& eventLoop() = 0;
     94    virtual EventLoopTaskGroup& eventLoop() = 0;
    9395
    9496    virtual const URL& url() const = 0;
  • trunk/Source/WebCore/dom/WindowEventLoop.cpp

    r252221 r252607  
    6060}
    6161
    62 void WindowEventLoop::queueTask(TaskSource source, ScriptExecutionContext& context, TaskFunction&& task)
     62void AbstractEventLoop::queueTask(std::unique_ptr<EventLoopTask>&& task)
    6363{
    64     ASSERT(isMainThread());
    65     ASSERT(is<Document>(context));
     64    ASSERT(task->group());
     65    ASSERT(isContextThread());
    6666    scheduleToRunIfNeeded();
    67     m_tasks.append(Task { source, WTFMove(task), downcast<Document>(context).identifier() });
     67    m_tasks.append(WTFMove(task));
    6868}
    6969
    70 void WindowEventLoop::suspend(Document&)
     70void AbstractEventLoop::resumeGroup(EventLoopTaskGroup& group)
    7171{
    72     ASSERT(isMainThread());
    73 }
    74 
    75 void WindowEventLoop::resume(Document& document)
    76 {
    77     ASSERT(isMainThread());
    78     if (!m_documentIdentifiersForSuspendedTasks.contains(document.identifier()))
     72    ASSERT(isContextThread());
     73    if (!m_groupsWithSuspenedTasks.contains(group))
    7974        return;
    8075    scheduleToRunIfNeeded();
    8176}
    8277
    83 void WindowEventLoop::stop(Document& document)
     78void AbstractEventLoop::stopGroup(EventLoopTaskGroup& group)
    8479{
    85     m_tasks.removeAllMatching([identifier = document.identifier()] (auto& task) {
    86         return task.documentIdentifier == identifier;
     80    ASSERT(isContextThread());
     81    m_tasks.removeAllMatching([&group] (auto& task) {
     82        return group.matchesTask(*task);
    8783    });
    8884}
    8985
    90 void WindowEventLoop::scheduleToRunIfNeeded()
     86void AbstractEventLoop::scheduleToRunIfNeeded()
    9187{
    9288    if (m_isScheduledToRun)
    9389        return;
     90    m_isScheduledToRun = true;
     91    scheduleToRun();
     92}
    9493
    95     m_isScheduledToRun = true;
     94void WindowEventLoop::scheduleToRun()
     95{
    9696    callOnMainThread([eventLoop = makeRef(*this)] () {
    97         eventLoop->m_isScheduledToRun = false;
    9897        eventLoop->run();
    9998    });
    10099}
    101100
    102 void WindowEventLoop::run()
     101bool WindowEventLoop::isContextThread() const
    103102{
     103    return isMainThread();
     104}
     105
     106void AbstractEventLoop::run()
     107{
     108    m_isScheduledToRun = false;
    104109    if (m_tasks.isEmpty())
    105110        return;
    106111
    107     Vector<Task> tasks = WTFMove(m_tasks);
    108     m_documentIdentifiersForSuspendedTasks.clear();
    109     Vector<Task> remainingTasks;
     112    auto tasks = std::exchange(m_tasks, { });
     113    m_groupsWithSuspenedTasks.clear();
     114    Vector<std::unique_ptr<EventLoopTask>> remainingTasks;
    110115    for (auto& task : tasks) {
    111         auto* document = Document::allDocumentsMap().get(task.documentIdentifier);
    112         if (!document || document->activeDOMObjectsAreStopped())
     116        auto* group = task->group();
     117        if (!group || group->isStoppedPermanently())
    113118            continue;
    114         if (document->activeDOMObjectsAreSuspended()) {
    115             m_documentIdentifiersForSuspendedTasks.add(task.documentIdentifier);
     119
     120        if (group->isSuspended()) {
     121            m_groupsWithSuspenedTasks.add(group);
    116122            remainingTasks.append(WTFMove(task));
    117123            continue;
    118124        }
    119         task.task();
     125
     126        task->execute();
    120127    }
    121128    for (auto& task : m_tasks)
     
    124131}
    125132
     133void AbstractEventLoop::clearAllTasks()
     134{
     135    m_tasks.clear();
     136    m_groupsWithSuspenedTasks.clear();
     137}
     138
     139class EventLoopFunctionDispatchTask : public EventLoopTask {
     140public:
     141    EventLoopFunctionDispatchTask(TaskSource source, EventLoopTaskGroup& group, AbstractEventLoop::TaskFunction&& function)
     142        : EventLoopTask(source, group)
     143        , m_function(WTFMove(function))
     144    {
     145    }
     146
     147    void execute() final { m_function(); }
     148
     149private:
     150    AbstractEventLoop::TaskFunction m_function;
     151};
     152
     153void EventLoopTaskGroup::queueTask(TaskSource source, AbstractEventLoop::TaskFunction&& function)
     154{
     155    return queueTask(makeUnique<EventLoopFunctionDispatchTask>(source, *this, WTFMove(function)));
     156}
     157
    126158} // namespace WebCore
  • trunk/Source/WebCore/dom/WindowEventLoop.h

    r252221 r252607  
    4242    ~WindowEventLoop();
    4343
    44     void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) override;
    45 
    46     void suspend(Document&);
    47     void resume(Document&);
    48     void stop(Document&);
    49 
    5044private:
    5145    WindowEventLoop(const RegistrableDomain&);
    5246
    53     void scheduleToRunIfNeeded();
    54     void run();
     47    void scheduleToRun() final;
     48    bool isContextThread() const final;
    5549
    56     struct Task {
    57         TaskSource source;
    58         TaskFunction task;
    59         DocumentIdentifier documentIdentifier;
    60     };
    61 
    62     // Use a global queue instead of multiple task queues since HTML5 spec allows UA to pick arbitrary queue.
    63     Vector<Task> m_tasks;
    64     HashSet<DocumentIdentifier> m_documentIdentifiersForSuspendedTasks;
    6550    RegistrableDomain m_domain;
    66     bool m_isScheduledToRun { false };
    6751};
    6852
  • trunk/Source/WebCore/fileapi/FileReader.cpp

    r251953 r252607  
    255255    uint64_t taskIdentifier = ++taskIdentifierSeed;
    256256    m_pendingTasks.add(taskIdentifier, WTFMove(task));
    257     context->eventLoop().queueTask(TaskSource::FileReading, *context, [this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this), taskIdentifier] {
     257    context->eventLoop().queueTask(TaskSource::FileReading, [this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this), taskIdentifier] {
    258258        auto task = m_pendingTasks.take(taskIdentifier);
    259259        if (task)
  • trunk/Source/WebCore/testing/Internals.cpp

    r252221 r252607  
    46854685        return Exception { NotSupportedError };
    46864686
    4687     context.eventLoop().queueTask(source, context, [callback = WTFMove(callback)]() {
     4687    context.eventLoop().queueTask(source, [callback = WTFMove(callback)]() {
    46884688        callback->handleEvent();
    46894689    });
  • trunk/Source/WebCore/workers/WorkerEventLoop.cpp

    r251968 r252607  
    4545
    4646WorkerEventLoop::WorkerEventLoop(ScriptExecutionContext& context)
    47     : ActiveDOMObject(&context)
     47    : ContextDestructionObserver(&context)
    4848{
    49     suspendIfNeeded();
    5049}
    5150
    52 void WorkerEventLoop::queueTask(TaskSource source, ScriptExecutionContext& context, TaskFunction&& function)
     51void WorkerEventLoop::scheduleToRun()
    5352{
    54     if (!scriptExecutionContext())
    55         return;
    56     ASSERT(scriptExecutionContext()->isContextThread());
    57     ASSERT_UNUSED(context, scriptExecutionContext() == &context);
    58     m_tasks.append({ source, WTFMove(function) });
    59     scheduleToRunIfNeeded();
    60 }
    61 
    62 const char* WorkerEventLoop::activeDOMObjectName() const
    63 {
    64     return "WorkerEventLoop";
    65 }
    66 
    67 void WorkerEventLoop::suspend(ReasonForSuspension)
    68 {
    69     ASSERT_NOT_REACHED();
    70 }
    71 
    72 void WorkerEventLoop::resume()
    73 {
    74     ASSERT_NOT_REACHED();
    75 }
    76 
    77 void WorkerEventLoop::stop()
    78 {
    79     m_tasks.clear();
    80 }
    81 
    82 void WorkerEventLoop::scheduleToRunIfNeeded()
    83 {
    84     auto* context = scriptExecutionContext();
    85     ASSERT(context);
    86     if (m_isScheduledToRun || m_tasks.isEmpty())
    87         return;
    88 
    89     m_isScheduledToRun = true;
    90     context->postTask([eventLoop = makeRef(*this)] (ScriptExecutionContext&) {
    91         eventLoop->m_isScheduledToRun = false;
     53    ASSERT(scriptExecutionContext());
     54    scriptExecutionContext()->postTask([eventLoop = makeRef(*this)] (ScriptExecutionContext&) {
    9255        eventLoop->run();
    9356    });
    9457}
    9558
    96 void WorkerEventLoop::run()
     59bool WorkerEventLoop::isContextThread() const
    9760{
    98     auto* context = scriptExecutionContext();
    99     if (!context || context->activeDOMObjectsAreStopped() || context->activeDOMObjectsAreSuspended())
    100         return;
    101     auto tasks = std::exchange(m_tasks, Vector<Task>());
    102     for (auto& task : tasks)
    103         task.task();
     61    return scriptExecutionContext()->isContextThread();
    10462}
    10563
  • trunk/Source/WebCore/workers/WorkerEventLoop.h

    r251792 r252607  
    3434class WorkletGlobalScope;
    3535
    36 class WorkerEventLoop final : public AbstractEventLoop, private ActiveDOMObject {
     36class WorkerEventLoop final : public AbstractEventLoop, private ContextDestructionObserver {
    3737public:
    3838    // Explicitly take WorkerGlobalScope and WorkletGlobalScope for documentation purposes.
     
    4343#endif
    4444
    45     void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) override;
    46 
    4745private:
    4846    explicit WorkerEventLoop(ScriptExecutionContext&);
    4947
    50     void scheduleToRunIfNeeded();
    51     void run();
    52 
    53     // ActiveDOMObject;
    54     const char* activeDOMObjectName() const override;
    55     void suspend(ReasonForSuspension) override;
    56     void resume() override;
    57     void stop() override;
    58 
    59     struct Task {
    60         TaskSource source;
    61         TaskFunction task;
    62     };
    63 
    64     Vector<Task> m_tasks;
    65     bool m_isScheduledToRun { false };
     48    void scheduleToRun() final;
     49    bool isContextThread() const;
    6650};
    6751
  • trunk/Source/WebCore/workers/WorkerGlobalScope.cpp

    r252060 r252607  
    106106}
    107107
    108 AbstractEventLoop& WorkerGlobalScope::eventLoop()
     108EventLoopTaskGroup& WorkerGlobalScope::eventLoop()
    109109{
    110110    ASSERT(isContextThread());
    111     if (!m_eventLoop)
     111    if (UNLIKELY(!m_defaultTaskGroup)) {
    112112        m_eventLoop = WorkerEventLoop::create(*this);
    113     return *m_eventLoop;
     113        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
     114        if (activeDOMObjectsAreStopped())
     115            m_defaultTaskGroup->stopAndDiscardAllTasks();
     116    }
     117    return *m_defaultTaskGroup;
    114118}
    115119
     
    126130#endif
    127131
     132    if (m_defaultTaskGroup)
     133        m_defaultTaskGroup->stopAndDiscardAllTasks();
    128134    stopActiveDOMObjects();
    129135
  • trunk/Source/WebCore/workers/WorkerGlobalScope.h

    r252060 r252607  
    4343namespace WebCore {
    4444
    45 class AbstractEventLoop;
    4645class ContentSecurityPolicyResponseHeaders;
    4746class Crypto;
     47class EventLoopTaskGroup;
    4848class MicrotaskQueue;
    4949class Performance;
     
    6868    virtual bool isServiceWorkerGlobalScope() const { return false; }
    6969
    70     AbstractEventLoop& eventLoop() final;
     70    EventLoopTaskGroup& eventLoop() final;
    7171
    7272    const URL& url() const final { return m_url; }
     
    199199
    200200    RefPtr<WorkerEventLoop> m_eventLoop;
     201    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
    201202
    202203    mutable WorkerEventQueue m_eventQueue;
  • trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp

    r251792 r252607  
    7878    if (!m_script)
    7979        return;
     80    if (m_defaultTaskGroup)
     81        m_defaultTaskGroup->stopAndDiscardAllTasks();
    8082    stopActiveDOMObjects();
    8183    removeRejectedPromiseTracker();
     
    9193}
    9294
    93 AbstractEventLoop& WorkletGlobalScope::eventLoop()
     95EventLoopTaskGroup& WorkletGlobalScope::eventLoop()
    9496{
    95     if (!m_eventLoop)
     97    if (UNLIKELY(!m_defaultTaskGroup)) {
    9698        m_eventLoop = WorkerEventLoop::create(*this);
    97     return *m_eventLoop;
     99        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
     100        if (activeDOMObjectsAreStopped())
     101            m_defaultTaskGroup->stopAndDiscardAllTasks();
     102    }
     103    return *m_defaultTaskGroup;
    98104}
    99105
  • trunk/Source/WebCore/worklets/WorkletGlobalScope.h

    r252030 r252607  
    4444namespace WebCore {
    4545
    46 class AbstractEventLoop;
     46class EventLoopTaskGroup;
    4747class WorkerEventLoop;
    4848class WorkletScriptController;
     
    6161    virtual bool isPaintWorkletGlobalScope() const { return false; }
    6262
    63     AbstractEventLoop& eventLoop() final;
     63    EventLoopTaskGroup& eventLoop() final;
    6464
    6565    const URL& url() const final { return m_code.url(); }
     
    136136
    137137    RefPtr<WorkerEventLoop> m_eventLoop;
     138    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
    138139
    139140    // FIXME: This is not implemented properly, it just satisfies the compiler.
Note: See TracChangeset for help on using the changeset viewer.