Diff
Modified: trunk/Source/WebCore/ChangeLog (252606 => 252607)
--- trunk/Source/WebCore/ChangeLog 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/ChangeLog 2019-11-19 00:54:57 UTC (rev 252607)
@@ -1,3 +1,127 @@
+2019-11-15 Ryosuke Niwa <[email protected]>
+
+ 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:
+
2019-11-18 Antti Koivisto <[email protected]>
Move RuleSet to Style namespace
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -106,7 +106,7 @@
// 4. Let promise be a new promise.
// 5. Run the following steps in parallel:
- context.eventLoop().queueTask(TaskSource::Networking, context, [this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
+ context.eventLoop().queueTask(TaskSource::Networking, [this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
// 5.1. Use this object's cdm instance to process certificate.
if (m_instance->setServerCertificate(WTFMove(certificate)) == CDMInstance::Failed) {
// 5.2. If the preceding step failed, resolve promise with a new DOMException whose name is the appropriate error name.
Modified: trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryEntry.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryEntry.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryEntry.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -57,7 +57,7 @@
auto* document = this->document();
if (result.hasException()) {
if (errorCallback && document) {
- document->eventLoop().queueTask(TaskSource::Networking, *document, [errorCallback = WTFMove(errorCallback), exception = result.releaseException(), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), exception = result.releaseException(), pendingActivity = WTFMove(pendingActivity)]() mutable {
errorCallback->handleEvent(DOMException::create(WTFMove(exception)));
});
}
@@ -66,7 +66,7 @@
auto entry = result.releaseReturnValue();
if (!matches(entry)) {
if (errorCallback && document) {
- document->eventLoop().queueTask(TaskSource::Networking, *document, [errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
errorCallback->handleEvent(DOMException::create(Exception { TypeMismatchError, "Entry at given path does not match expected type"_s }));
});
}
@@ -73,7 +73,7 @@
return;
}
if (successCallback && document) {
- document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), entry = WTFMove(entry), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), entry = WTFMove(entry), pendingActivity = WTFMove(pendingActivity)]() mutable {
successCallback->handleEvent(WTFMove(entry));
});
}
Modified: trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryReader.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryReader.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryReader.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -89,7 +89,7 @@
if (result.hasException()) {
m_error = result.releaseException();
if (errorCallback && document) {
- document->eventLoop().queueTask(TaskSource::Networking, *document, [this, errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [this, errorCallback = WTFMove(errorCallback), pendingActivity = WTFMove(pendingActivity)]() mutable {
errorCallback->handleEvent(DOMException::create(*m_error));
});
}
@@ -97,7 +97,7 @@
}
m_isDone = true;
if (document) {
- document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), pendingActivity = WTFMove(pendingActivity), result = result.releaseReturnValue()]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), pendingActivity = WTFMove(pendingActivity), result = result.releaseReturnValue()]() mutable {
successCallback->handleEvent(WTFMove(result));
});
}
Modified: trunk/Source/WebCore/Modules/entriesapi/FileSystemEntry.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/entriesapi/FileSystemEntry.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/entriesapi/FileSystemEntry.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -77,7 +77,7 @@
if (!document)
return;
- document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
if (result.hasException()) {
if (errorCallback)
errorCallback->handleEvent(DOMException::create(result.releaseException()));
Modified: trunk/Source/WebCore/Modules/entriesapi/FileSystemFileEntry.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/entriesapi/FileSystemFileEntry.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/entriesapi/FileSystemFileEntry.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -48,7 +48,7 @@
if (!document)
return;
- document->eventLoop().queueTask(TaskSource::Networking, *document, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
+ document->eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), result = WTFMove(result), pendingActivity = WTFMove(pendingActivity)]() mutable {
if (result.hasException()) {
if (errorCallback)
errorCallback->handleEvent(DOMException::create(result.releaseException()));
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -216,7 +216,7 @@
if (!document)
return;
- document->eventLoop().queueTask(TaskSource::Networking, *document, [pendingActivity = makePendingActivity(*this), function = WTFMove(function)] {
+ document->eventLoop().queueTask(TaskSource::Networking, [pendingActivity = makePendingActivity(*this), function = WTFMove(function)] {
function();
});
}
Modified: trunk/Source/WebCore/Modules/notifications/Notification.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/notifications/Notification.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/notifications/Notification.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -152,7 +152,7 @@
if (!document)
return;
- document->eventLoop().queueTask(TaskSource::UserInteraction, *document, WTFMove(task));
+ document->eventLoop().queueTask(TaskSource::UserInteraction, WTFMove(task));
}
void Notification::dispatchShowEvent()
Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -689,7 +689,7 @@
LockHolder locker(m_transactionInProgressMutex);
if (!m_isTransactionQueueEnabled) {
if (errorCallback) {
- m_document->eventLoop().queueTask(TaskSource::Networking, m_document, [errorCallback = makeRef(*errorCallback)]() {
+ m_document->eventLoop().queueTask(TaskSource::Networking, [errorCallback = makeRef(*errorCallback)]() {
errorCallback->handleEvent(SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed"));
});
}
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -210,7 +210,7 @@
if (database->isNew() && creationCallback.get()) {
LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database.get());
database->setHasPendingCreationEvent(true);
- database->m_document->eventLoop().queueTask(TaskSource::Networking, database->m_document, [creationCallback, database]() {
+ database->m_document->eventLoop().queueTask(TaskSource::Networking, [creationCallback, database]() {
creationCallback->handleEvent(*database);
database->setHasPendingCreationEvent(false);
});
Modified: trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp (252606 => 252607)
--- trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -141,7 +141,7 @@
if (!errorCallback)
return;
- m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [errorCallback = WTFMove(errorCallback)]() mutable {
+ m_database->document().eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback)]() mutable {
errorCallback->handleEvent(SQLError::create(SQLError::DATABASE_ERR, "the database was closed"));
});
}
@@ -415,7 +415,7 @@
// error to have occurred in this transaction.
RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap();
if (errorCallback) {
- m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [errorCallback = WTFMove(errorCallback), transactionError = m_transactionError]() mutable {
+ m_database->document().eventLoop().queueTask(TaskSource::Networking, [errorCallback = WTFMove(errorCallback), transactionError = m_transactionError]() mutable {
errorCallback->handleEvent(*transactionError);
});
}
@@ -466,7 +466,7 @@
// Spec 4.3.2.8: Deliver success callback.
RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap();
if (successCallback) {
- m_database->document().eventLoop().queueTask(TaskSource::Networking, m_database->document(), [successCallback = WTFMove(successCallback)]() mutable {
+ m_database->document().eventLoop().queueTask(TaskSource::Networking, [successCallback = WTFMove(successCallback)]() mutable {
successCallback->handleEvent();
});
}
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp (252606 => 252607)
--- trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -51,7 +51,7 @@
if (activeDOMObjectsAreSuspended()) {
JSC::Strong<JSC::Unknown, ShouldStrongDestructorGrabLock::Yes> strongResolution(lexicalGlobalObject.vm(), resolution);
- scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, *scriptExecutionContext(), [this, protectedThis = makeRef(*this), mode, strongResolution = WTFMove(strongResolution)]() mutable {
+ scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = makeRef(*this), mode, strongResolution = WTFMove(strongResolution)]() mutable {
if (shouldIgnoreRequestToFulfill())
return;
@@ -83,7 +83,7 @@
return;
if (activeDOMObjectsAreSuspended()) {
- scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, *scriptExecutionContext(), [this, protectedThis = makeRef(*this), callback = WTFMove(callback)]() mutable {
+ scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = makeRef(*this), callback = WTFMove(callback)]() mutable {
whenSettled(WTFMove(callback));
});
return;
Modified: trunk/Source/WebCore/dom/AbstractEventLoop.h (252606 => 252607)
--- trunk/Source/WebCore/dom/AbstractEventLoop.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/AbstractEventLoop.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -28,21 +28,125 @@
#include "TaskSource.h"
#include <wtf/Function.h>
#include <wtf/RefCounted.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/WeakHashSet.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
+class EventLoopTaskGroup;
+class EventTarget;
class ScriptExecutionContext;
+class EventLoopTask {
+ WTF_MAKE_NONCOPYABLE(EventLoopTask);
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ virtual ~EventLoopTask() = default;
+
+ TaskSource taskSource() { return m_taskSource; }
+ virtual void execute() = 0;
+
+ EventLoopTaskGroup* group() const { return m_group.get(); }
+
+protected:
+ EventLoopTask(TaskSource, EventLoopTaskGroup&);
+
+private:
+ const TaskSource m_taskSource;
+ WeakPtr<EventLoopTaskGroup> m_group;
+};
+
// https://html.spec.whatwg.org/multipage/webappapis.html#event-loop
-class AbstractEventLoop : public RefCounted<AbstractEventLoop> {
+class AbstractEventLoop : public RefCounted<AbstractEventLoop>, public CanMakeWeakPtr<AbstractEventLoop> {
public:
virtual ~AbstractEventLoop() = default;
- typedef WTF::Function<void ()> TaskFunction;
- virtual void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) = 0;
+ typedef Function<void ()> TaskFunction;
+ void queueTask(std::unique_ptr<EventLoopTask>&&);
+ void resumeGroup(EventLoopTaskGroup&);
+ void stopGroup(EventLoopTaskGroup&);
+
protected:
AbstractEventLoop() = default;
+ void run();
+ void clearAllTasks();
+
+private:
+ void scheduleToRunIfNeeded();
+ virtual void scheduleToRun() = 0;
+ virtual bool isContextThread() const = 0;
+
+ // Use a global queue instead of multiple task queues since HTML5 spec allows UA to pick arbitrary queue.
+ Vector<std::unique_ptr<EventLoopTask>> m_tasks;
+ WeakHashSet<EventLoopTaskGroup> m_groupsWithSuspenedTasks;
+ bool m_isScheduledToRun { false };
};
+class EventLoopTaskGroup : public CanMakeWeakPtr<EventLoopTaskGroup> {
+ WTF_MAKE_NONCOPYABLE(EventLoopTaskGroup);
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ EventLoopTaskGroup(AbstractEventLoop& eventLoop)
+ : m_eventLoop(makeWeakPtr(eventLoop))
+ {
+ }
+
+ bool matchesTask(EventLoopTask& task) const
+ {
+ auto* group = task.group();
+ return group == this;
+ }
+
+ void stopAndDiscardAllTasks()
+ {
+ m_state = State::Stopped;
+ if (auto* eventLoop = m_eventLoop.get())
+ eventLoop->stopGroup(*this);
+ }
+
+ void suspend()
+ {
+ ASSERT(m_state != State::Stopped);
+ m_state = State::Suspended;
+ // We don't remove suspended tasks to preserve the ordering.
+ // AbstractEventLoop::run checks whether each task's group is suspended or not.
+ }
+
+ void resume()
+ {
+ ASSERT(m_state != State::Stopped);
+ m_state = State::Running;
+ if (auto* eventLoop = m_eventLoop.get())
+ eventLoop->resumeGroup(*this);
+ }
+
+ bool isStoppedPermanently() { return m_state == State::Stopped; }
+ bool isSuspended() { return m_state == State::Suspended; }
+
+ void queueTask(std::unique_ptr<EventLoopTask>&& task)
+ {
+ if (m_state == State::Stopped || !m_eventLoop)
+ return;
+ ASSERT(task->group() == this);
+ m_eventLoop->queueTask(WTFMove(task));
+ }
+
+ WEBCORE_EXPORT void queueTask(TaskSource, AbstractEventLoop::TaskFunction&&);
+
+private:
+ enum class State : uint8_t { Running, Suspended, Stopped };
+
+ WeakPtr<AbstractEventLoop> m_eventLoop;
+ State m_state { State::Running };
+};
+
+inline EventLoopTask::EventLoopTask(TaskSource source, EventLoopTaskGroup& group)
+ : m_taskSource(source)
+ , m_group(makeWeakPtr(group))
+{ }
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/ActiveDOMObject.cpp (252606 => 252607)
--- trunk/Source/WebCore/dom/ActiveDOMObject.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/ActiveDOMObject.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -135,12 +135,48 @@
return scriptExecutionContext() && !scriptExecutionContext()->activeDOMObjectsAreStopped() && !scriptExecutionContext()->activeDOMObjectsAreSuspended();
}
-void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void ()>&& task)
+void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void ()>&& function)
{
auto* context = scriptExecutionContext();
if (!context)
return;
- context->eventLoop().queueTask(source, *context, WTFMove(task));
+ context->eventLoop().queueTask(source, WTFMove(function));
}
+class ActiveDOMObjectEventDispatchTask : public EventLoopTask {
+public:
+ ActiveDOMObjectEventDispatchTask(TaskSource source, EventLoopTaskGroup& group, ActiveDOMObject& object, EventTarget& target, Ref<Event>&& event)
+ : EventLoopTask(source, group)
+ , m_object(object)
+ , m_target(target)
+ , m_event(WTFMove(event))
+ {
+ ++m_object.m_pendingActivityCount;
+ }
+
+ ~ActiveDOMObjectEventDispatchTask()
+ {
+ ASSERT(m_object.m_pendingActivityCount);
+ --m_object.m_pendingActivityCount;
+ }
+
+ void execute() final { m_target->dispatchEvent(m_event.get()); }
+
+private:
+ ActiveDOMObject& m_object;
+ Ref<EventTarget> m_target;
+ Ref<Event> m_event;
+};
+
+void ActiveDOMObject::queueTaskToDispatchEventInternal(EventTarget& target, TaskSource source, Ref<Event>&& event)
+{
+ ASSERT(!event->target() || &target == event->target());
+ auto* context = scriptExecutionContext();
+ if (!context)
+ return;
+ auto& eventLoopTaskGroup = context->eventLoop();
+ auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, target, WTFMove(event));
+ eventLoopTaskGroup.queueTask(WTFMove(task));
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/ActiveDOMObject.h (252606 => 252607)
--- trunk/Source/WebCore/dom/ActiveDOMObject.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/ActiveDOMObject.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -37,6 +37,9 @@
namespace WebCore {
class Document;
+class Event;
+class EventLoopTaskGroup;
+class EventTarget;
enum class ReasonForSuspension {
_javascript_DebuggerPaused,
@@ -116,7 +119,7 @@
template<typename T>
static void queueTaskKeepingObjectAlive(T& object, TaskSource source, Function<void ()>&& task)
{
- object.queueTaskInEventLoop(source, [protectedObject = makeRef(object), activity = object.makePendingActivity(object), task = WTFMove(task)] () {
+ object.queueTaskInEventLoop(source, [protectedObject = makeRef(object), activity = object.ActiveDOMObject::makePendingActivity(object), task = WTFMove(task)] () {
task();
});
}
@@ -124,10 +127,7 @@
template<typename EventTargetType, typename EventType>
static void queueTaskToDispatchEvent(EventTargetType& target, TaskSource source, Ref<EventType>&& event)
{
- ASSERT(!event->target() || &target == event->target());
- queueTaskKeepingObjectAlive(target, source, [&target, event = WTFMove(event)] () mutable {
- target.dispatchEvent(event.get());
- });
+ target.queueTaskToDispatchEventInternal(target, source, WTFMove(event));
}
protected:
@@ -141,6 +141,7 @@
ActiveDOMObject(ScriptExecutionContext*, CheckedScriptExecutionContextType);
void queueTaskInEventLoop(TaskSource, Function<void ()>&&);
+ void queueTaskToDispatchEventInternal(EventTarget&, TaskSource, Ref<Event>&&);
unsigned m_pendingActivityCount { 0 };
#if !ASSERT_DISABLED
@@ -147,6 +148,8 @@
bool m_suspendIfNeededWasCalled { false };
Ref<Thread> m_creationThread { Thread::current() };
#endif
+
+ friend class ActiveDOMObjectEventDispatchTask;
};
#if ASSERT_DISABLED
Modified: trunk/Source/WebCore/dom/Document.cpp (252606 => 252607)
--- trunk/Source/WebCore/dom/Document.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/Document.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -2646,8 +2646,8 @@
void Document::suspendActiveDOMObjects(ReasonForSuspension why)
{
- if (m_eventLoop)
- m_eventLoop->suspend(*this);
+ if (m_documentTaskGroup)
+ m_documentTaskGroup->suspend();
ScriptExecutionContext::suspendActiveDOMObjects(why);
suspendDeviceMotionAndOrientationUpdates();
platformSuspendOrStopActiveDOMObjects();
@@ -2655,8 +2655,8 @@
void Document::resumeActiveDOMObjects(ReasonForSuspension why)
{
- if (m_eventLoop)
- m_eventLoop->resume(*this);
+ if (m_documentTaskGroup)
+ m_documentTaskGroup->resume();
ScriptExecutionContext::resumeActiveDOMObjects(why);
resumeDeviceMotionAndOrientationUpdates();
// FIXME: For iOS, do we need to add content change observers that were removed in Document::suspendActiveDOMObjects()?
@@ -2664,8 +2664,8 @@
void Document::stopActiveDOMObjects()
{
- if (m_eventLoop)
- m_eventLoop->stop(*this);
+ if (m_documentTaskGroup)
+ m_documentTaskGroup->stopAndDiscardAllTasks();
ScriptExecutionContext::stopActiveDOMObjects();
platformSuspendOrStopActiveDOMObjects();
}
@@ -6243,12 +6243,18 @@
task.performTask(*this);
}
-AbstractEventLoop& Document::eventLoop()
+EventLoopTaskGroup& Document::eventLoop()
{
ASSERT(isMainThread());
- if (UNLIKELY(!m_eventLoop))
+ if (UNLIKELY(!m_documentTaskGroup)) {
m_eventLoop = WindowEventLoop::ensureForRegistrableDomain(RegistrableDomain { securityOrigin().data() });
- return *m_eventLoop;
+ m_documentTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
+ if (activeDOMObjectsAreStopped())
+ m_documentTaskGroup->stopAndDiscardAllTasks();
+ else if (activeDOMObjectsAreSuspended())
+ m_documentTaskGroup->suspend();
+ }
+ return *m_documentTaskGroup;
}
void Document::suspendScheduledTasks(ReasonForSuspension reason)
Modified: trunk/Source/WebCore/dom/Document.h (252606 => 252607)
--- trunk/Source/WebCore/dom/Document.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/Document.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -121,6 +121,7 @@
class DocumentTimeline;
class DocumentType;
class EditingBehavior;
+class EventLoopTaskGroup;
class ExtensionStyleSheets;
class FloatQuad;
class FloatRect;
@@ -1063,7 +1064,7 @@
WEBCORE_EXPORT void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
- AbstractEventLoop& eventLoop() final;
+ EventLoopTaskGroup& eventLoop() final;
ScriptedAnimationController* scriptedAnimationController() { return m_scriptedAnimationController.get(); }
void suspendScriptedAnimationControllerCallbacks();
@@ -2064,6 +2065,7 @@
DocumentIdentifier m_identifier;
RefPtr<WindowEventLoop> m_eventLoop;
+ std::unique_ptr<EventLoopTaskGroup> m_documentTaskGroup;
#if ENABLE(SERVICE_WORKER)
RefPtr<SWClientConnection> m_serviceWorkerConnection;
Modified: trunk/Source/WebCore/dom/IdleCallbackController.cpp (252606 => 252607)
--- trunk/Source/WebCore/dom/IdleCallbackController.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/IdleCallbackController.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -71,7 +71,7 @@
void IdleCallbackController::queueTaskToStartIdlePeriod()
{
- m_document->eventLoop().queueTask(TaskSource::IdleTask, *m_document, [protectedDocument = makeRef(*m_document), this]() {
+ m_document->eventLoop().queueTask(TaskSource::IdleTask, [protectedDocument = makeRef(*m_document), this] {
RELEASE_ASSERT(protectedDocument->idleCallbackController() == this);
startIdlePeriod();
});
@@ -100,7 +100,7 @@
void IdleCallbackController::queueTaskToInvokeIdleCallbacks(MonotonicTime deadline)
{
- m_document->eventLoop().queueTask(TaskSource::IdleTask, *m_document, [protectedDocument = makeRef(*m_document), deadline, this]() {
+ m_document->eventLoop().queueTask(TaskSource::IdleTask, [protectedDocument = makeRef(*m_document), deadline, this] {
RELEASE_ASSERT(protectedDocument->idleCallbackController() == this);
invokeIdleCallbacks(deadline);
});
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (252606 => 252607)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -57,6 +57,7 @@
class CachedScript;
class DatabaseContext;
class EventQueue;
+class EventLoopTaskGroup;
class EventTarget;
class MessagePort;
class PublicURLManager;
@@ -64,6 +65,7 @@
class ResourceRequest;
class SecurityOrigin;
class SocketProvider;
+enum class TaskSource : uint8_t;
#if ENABLE(SERVICE_WORKER)
class ServiceWorker;
@@ -89,7 +91,7 @@
virtual bool isContextThread() const { return true; }
virtual bool isJSExecutionForbidden() const = 0;
- virtual AbstractEventLoop& eventLoop() = 0;
+ virtual EventLoopTaskGroup& eventLoop() = 0;
virtual const URL& url() const = 0;
virtual URL completeURL(const String& url) const = 0;
Modified: trunk/Source/WebCore/dom/WindowEventLoop.cpp (252606 => 252607)
--- trunk/Source/WebCore/dom/WindowEventLoop.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/WindowEventLoop.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -59,64 +59,71 @@
RELEASE_ASSERT(didRemove);
}
-void WindowEventLoop::queueTask(TaskSource source, ScriptExecutionContext& context, TaskFunction&& task)
+void AbstractEventLoop::queueTask(std::unique_ptr<EventLoopTask>&& task)
{
- ASSERT(isMainThread());
- ASSERT(is<Document>(context));
+ ASSERT(task->group());
+ ASSERT(isContextThread());
scheduleToRunIfNeeded();
- m_tasks.append(Task { source, WTFMove(task), downcast<Document>(context).identifier() });
+ m_tasks.append(WTFMove(task));
}
-void WindowEventLoop::suspend(Document&)
+void AbstractEventLoop::resumeGroup(EventLoopTaskGroup& group)
{
- ASSERT(isMainThread());
-}
-
-void WindowEventLoop::resume(Document& document)
-{
- ASSERT(isMainThread());
- if (!m_documentIdentifiersForSuspendedTasks.contains(document.identifier()))
+ ASSERT(isContextThread());
+ if (!m_groupsWithSuspenedTasks.contains(group))
return;
scheduleToRunIfNeeded();
}
-void WindowEventLoop::stop(Document& document)
+void AbstractEventLoop::stopGroup(EventLoopTaskGroup& group)
{
- m_tasks.removeAllMatching([identifier = document.identifier()] (auto& task) {
- return task.documentIdentifier == identifier;
+ ASSERT(isContextThread());
+ m_tasks.removeAllMatching([&group] (auto& task) {
+ return group.matchesTask(*task);
});
}
-void WindowEventLoop::scheduleToRunIfNeeded()
+void AbstractEventLoop::scheduleToRunIfNeeded()
{
if (m_isScheduledToRun)
return;
+ m_isScheduledToRun = true;
+ scheduleToRun();
+}
- m_isScheduledToRun = true;
+void WindowEventLoop::scheduleToRun()
+{
callOnMainThread([eventLoop = makeRef(*this)] () {
- eventLoop->m_isScheduledToRun = false;
eventLoop->run();
});
}
-void WindowEventLoop::run()
+bool WindowEventLoop::isContextThread() const
{
+ return isMainThread();
+}
+
+void AbstractEventLoop::run()
+{
+ m_isScheduledToRun = false;
if (m_tasks.isEmpty())
return;
- Vector<Task> tasks = WTFMove(m_tasks);
- m_documentIdentifiersForSuspendedTasks.clear();
- Vector<Task> remainingTasks;
+ auto tasks = std::exchange(m_tasks, { });
+ m_groupsWithSuspenedTasks.clear();
+ Vector<std::unique_ptr<EventLoopTask>> remainingTasks;
for (auto& task : tasks) {
- auto* document = Document::allDocumentsMap().get(task.documentIdentifier);
- if (!document || document->activeDOMObjectsAreStopped())
+ auto* group = task->group();
+ if (!group || group->isStoppedPermanently())
continue;
- if (document->activeDOMObjectsAreSuspended()) {
- m_documentIdentifiersForSuspendedTasks.add(task.documentIdentifier);
+
+ if (group->isSuspended()) {
+ m_groupsWithSuspenedTasks.add(group);
remainingTasks.append(WTFMove(task));
continue;
}
- task.task();
+
+ task->execute();
}
for (auto& task : m_tasks)
remainingTasks.append(WTFMove(task));
@@ -123,4 +130,29 @@
m_tasks = WTFMove(remainingTasks);
}
+void AbstractEventLoop::clearAllTasks()
+{
+ m_tasks.clear();
+ m_groupsWithSuspenedTasks.clear();
+}
+
+class EventLoopFunctionDispatchTask : public EventLoopTask {
+public:
+ EventLoopFunctionDispatchTask(TaskSource source, EventLoopTaskGroup& group, AbstractEventLoop::TaskFunction&& function)
+ : EventLoopTask(source, group)
+ , m_function(WTFMove(function))
+ {
+ }
+
+ void execute() final { m_function(); }
+
+private:
+ AbstractEventLoop::TaskFunction m_function;
+};
+
+void EventLoopTaskGroup::queueTask(TaskSource source, AbstractEventLoop::TaskFunction&& function)
+{
+ return queueTask(makeUnique<EventLoopFunctionDispatchTask>(source, *this, WTFMove(function)));
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/WindowEventLoop.h (252606 => 252607)
--- trunk/Source/WebCore/dom/WindowEventLoop.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/dom/WindowEventLoop.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -41,29 +41,13 @@
~WindowEventLoop();
- void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) override;
-
- void suspend(Document&);
- void resume(Document&);
- void stop(Document&);
-
private:
WindowEventLoop(const RegistrableDomain&);
- void scheduleToRunIfNeeded();
- void run();
+ void scheduleToRun() final;
+ bool isContextThread() const final;
- struct Task {
- TaskSource source;
- TaskFunction task;
- DocumentIdentifier documentIdentifier;
- };
-
- // Use a global queue instead of multiple task queues since HTML5 spec allows UA to pick arbitrary queue.
- Vector<Task> m_tasks;
- HashSet<DocumentIdentifier> m_documentIdentifiersForSuspendedTasks;
RegistrableDomain m_domain;
- bool m_isScheduledToRun { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/fileapi/FileReader.cpp (252606 => 252607)
--- trunk/Source/WebCore/fileapi/FileReader.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/fileapi/FileReader.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -254,7 +254,7 @@
static uint64_t taskIdentifierSeed = 0;
uint64_t taskIdentifier = ++taskIdentifierSeed;
m_pendingTasks.add(taskIdentifier, WTFMove(task));
- context->eventLoop().queueTask(TaskSource::FileReading, *context, [this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this), taskIdentifier] {
+ context->eventLoop().queueTask(TaskSource::FileReading, [this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this), taskIdentifier] {
auto task = m_pendingTasks.take(taskIdentifier);
if (task)
task();
Modified: trunk/Source/WebCore/testing/Internals.cpp (252606 => 252607)
--- trunk/Source/WebCore/testing/Internals.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/testing/Internals.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -4684,7 +4684,7 @@
else
return Exception { NotSupportedError };
- context.eventLoop().queueTask(source, context, [callback = WTFMove(callback)]() {
+ context.eventLoop().queueTask(source, [callback = WTFMove(callback)]() {
callback->handleEvent();
});
Modified: trunk/Source/WebCore/workers/WorkerEventLoop.cpp (252606 => 252607)
--- trunk/Source/WebCore/workers/WorkerEventLoop.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/workers/WorkerEventLoop.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -44,63 +44,21 @@
#endif
WorkerEventLoop::WorkerEventLoop(ScriptExecutionContext& context)
- : ActiveDOMObject(&context)
+ : ContextDestructionObserver(&context)
{
- suspendIfNeeded();
}
-void WorkerEventLoop::queueTask(TaskSource source, ScriptExecutionContext& context, TaskFunction&& function)
+void WorkerEventLoop::scheduleToRun()
{
- if (!scriptExecutionContext())
- return;
- ASSERT(scriptExecutionContext()->isContextThread());
- ASSERT_UNUSED(context, scriptExecutionContext() == &context);
- m_tasks.append({ source, WTFMove(function) });
- scheduleToRunIfNeeded();
-}
-
-const char* WorkerEventLoop::activeDOMObjectName() const
-{
- return "WorkerEventLoop";
-}
-
-void WorkerEventLoop::suspend(ReasonForSuspension)
-{
- ASSERT_NOT_REACHED();
-}
-
-void WorkerEventLoop::resume()
-{
- ASSERT_NOT_REACHED();
-}
-
-void WorkerEventLoop::stop()
-{
- m_tasks.clear();
-}
-
-void WorkerEventLoop::scheduleToRunIfNeeded()
-{
- auto* context = scriptExecutionContext();
- ASSERT(context);
- if (m_isScheduledToRun || m_tasks.isEmpty())
- return;
-
- m_isScheduledToRun = true;
- context->postTask([eventLoop = makeRef(*this)] (ScriptExecutionContext&) {
- eventLoop->m_isScheduledToRun = false;
+ ASSERT(scriptExecutionContext());
+ scriptExecutionContext()->postTask([eventLoop = makeRef(*this)] (ScriptExecutionContext&) {
eventLoop->run();
});
}
-void WorkerEventLoop::run()
+bool WorkerEventLoop::isContextThread() const
{
- auto* context = scriptExecutionContext();
- if (!context || context->activeDOMObjectsAreStopped() || context->activeDOMObjectsAreSuspended())
- return;
- auto tasks = std::exchange(m_tasks, Vector<Task>());
- for (auto& task : tasks)
- task.task();
+ return scriptExecutionContext()->isContextThread();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/WorkerEventLoop.h (252606 => 252607)
--- trunk/Source/WebCore/workers/WorkerEventLoop.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/workers/WorkerEventLoop.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -33,7 +33,7 @@
class WorkerGlobalScope;
class WorkletGlobalScope;
-class WorkerEventLoop final : public AbstractEventLoop, private ActiveDOMObject {
+class WorkerEventLoop final : public AbstractEventLoop, private ContextDestructionObserver {
public:
// Explicitly take WorkerGlobalScope and WorkletGlobalScope for documentation purposes.
static Ref<WorkerEventLoop> create(WorkerGlobalScope&);
@@ -42,27 +42,11 @@
static Ref<WorkerEventLoop> create(WorkletGlobalScope&);
#endif
- void queueTask(TaskSource, ScriptExecutionContext&, TaskFunction&&) override;
-
private:
explicit WorkerEventLoop(ScriptExecutionContext&);
- void scheduleToRunIfNeeded();
- void run();
-
- // ActiveDOMObject;
- const char* activeDOMObjectName() const override;
- void suspend(ReasonForSuspension) override;
- void resume() override;
- void stop() override;
-
- struct Task {
- TaskSource source;
- TaskFunction task;
- };
-
- Vector<Task> m_tasks;
- bool m_isScheduledToRun { false };
+ void scheduleToRun() final;
+ bool isContextThread() const;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (252606 => 252607)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -105,12 +105,16 @@
thread().workerReportingProxy().workerGlobalScopeDestroyed();
}
-AbstractEventLoop& WorkerGlobalScope::eventLoop()
+EventLoopTaskGroup& WorkerGlobalScope::eventLoop()
{
ASSERT(isContextThread());
- if (!m_eventLoop)
+ if (UNLIKELY(!m_defaultTaskGroup)) {
m_eventLoop = WorkerEventLoop::create(*this);
- return *m_eventLoop;
+ m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
+ if (activeDOMObjectsAreStopped())
+ m_defaultTaskGroup->stopAndDiscardAllTasks();
+ }
+ return *m_defaultTaskGroup;
}
String WorkerGlobalScope::origin() const
@@ -125,6 +129,8 @@
stopIndexedDatabase();
#endif
+ if (m_defaultTaskGroup)
+ m_defaultTaskGroup->stopAndDiscardAllTasks();
stopActiveDOMObjects();
if (m_cacheStorageConnection)
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (252606 => 252607)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -42,9 +42,9 @@
namespace WebCore {
-class AbstractEventLoop;
class ContentSecurityPolicyResponseHeaders;
class Crypto;
+class EventLoopTaskGroup;
class MicrotaskQueue;
class Performance;
class ScheduledAction;
@@ -67,7 +67,7 @@
virtual bool isDedicatedWorkerGlobalScope() const { return false; }
virtual bool isServiceWorkerGlobalScope() const { return false; }
- AbstractEventLoop& eventLoop() final;
+ EventLoopTaskGroup& eventLoop() final;
const URL& url() const final { return m_url; }
String origin() const final;
@@ -198,6 +198,7 @@
bool m_shouldBypassMainWorldContentSecurityPolicy;
RefPtr<WorkerEventLoop> m_eventLoop;
+ std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
mutable WorkerEventQueue m_eventQueue;
Modified: trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp (252606 => 252607)
--- trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp 2019-11-19 00:54:57 UTC (rev 252607)
@@ -77,6 +77,8 @@
{
if (!m_script)
return;
+ if (m_defaultTaskGroup)
+ m_defaultTaskGroup->stopAndDiscardAllTasks();
stopActiveDOMObjects();
removeRejectedPromiseTracker();
removeAllEventListeners();
@@ -90,11 +92,15 @@
return scopes;
}
-AbstractEventLoop& WorkletGlobalScope::eventLoop()
+EventLoopTaskGroup& WorkletGlobalScope::eventLoop()
{
- if (!m_eventLoop)
+ if (UNLIKELY(!m_defaultTaskGroup)) {
m_eventLoop = WorkerEventLoop::create(*this);
- return *m_eventLoop;
+ m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
+ if (activeDOMObjectsAreStopped())
+ m_defaultTaskGroup->stopAndDiscardAllTasks();
+ }
+ return *m_defaultTaskGroup;
}
String WorkletGlobalScope::origin() const
Modified: trunk/Source/WebCore/worklets/WorkletGlobalScope.h (252606 => 252607)
--- trunk/Source/WebCore/worklets/WorkletGlobalScope.h 2019-11-19 00:53:03 UTC (rev 252606)
+++ trunk/Source/WebCore/worklets/WorkletGlobalScope.h 2019-11-19 00:54:57 UTC (rev 252607)
@@ -43,7 +43,7 @@
namespace WebCore {
-class AbstractEventLoop;
+class EventLoopTaskGroup;
class WorkerEventLoop;
class WorkletScriptController;
@@ -60,7 +60,7 @@
virtual bool isPaintWorkletGlobalScope() const { return false; }
- AbstractEventLoop& eventLoop() final;
+ EventLoopTaskGroup& eventLoop() final;
const URL& url() const final { return m_code.url(); }
String origin() const final;
@@ -135,6 +135,7 @@
Ref<SecurityOrigin> m_topOrigin;
RefPtr<WorkerEventLoop> m_eventLoop;
+ std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
// FIXME: This is not implemented properly, it just satisfies the compiler.
// https://bugs.webkit.org/show_bug.cgi?id=191136