Diff
Modified: branches/safari-607-branch/Source/WebCore/PlatformWin.cmake (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/PlatformWin.cmake 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/PlatformWin.cmake 2021-04-28 18:12:18 UTC (rev 276724)
@@ -34,6 +34,7 @@
platform/Cursor.cpp
platform/LocalizedStrings.cpp
platform/StaticPasteboard.cpp
+ platform/SuspendableTaskQueue.cpp
platform/audio/PlatformMediaSessionManager.cpp
Modified: branches/safari-607-branch/Source/WebCore/Sources.txt (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/Sources.txt 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/Sources.txt 2021-04-28 18:12:18 UTC (rev 276724)
@@ -1592,6 +1592,7 @@
platform/SharedBufferChunkReader.cpp
platform/SharedStringHash.cpp
platform/StaticPasteboard.cpp
+platform/SuspendableTaskQueue.cpp
platform/Theme.cpp
platform/ThreadGlobalData.cpp
platform/ThreadTimers.cpp
Modified: branches/safari-607-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-04-28 18:12:18 UTC (rev 276724)
@@ -1262,6 +1262,7 @@
46C696CC1E7205FC00597937 /* CPUMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46C696CA1E7205E400597937 /* CPUMonitor.cpp */; };
46C83EFE1A9BBE2900A79A41 /* GeoNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C83EFC1A9BBE2900A79A41 /* GeoNotifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
46CA9C441F97BBE9004CFC3A /* VisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = 46CA9C411F97BBE7004CFC3A /* VisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 46CDC1F023466B2300D2E70E /* SuspendableTaskQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 466907F82346686200EFEFF0 /* SuspendableTaskQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
46DBB6501AB8C96F00D9A813 /* PowerObserverMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DBB64E1AB8C96F00D9A813 /* PowerObserverMac.h */; };
46DFF4981DC2603100B80B48 /* ShadowRootMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DFF4961DC2601300B80B48 /* ShadowRootMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
46DFF49C1DC2620B00B80B48 /* JSShadowRootMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DFF49A1DC261F900B80B48 /* JSShadowRootMode.h */; };
@@ -7636,6 +7637,8 @@
458FE4071589DF0B005609E6 /* RenderSearchField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSearchField.cpp; sourceTree = "<group>"; };
458FE4081589DF0B005609E6 /* RenderSearchField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSearchField.h; sourceTree = "<group>"; };
45FEA5CD156DDE8C00654101 /* Decimal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decimal.cpp; sourceTree = "<group>"; };
+ 466907F62346686200EFEFF0 /* SuspendableTaskQueue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SuspendableTaskQueue.cpp; sourceTree = "<group>"; };
+ 466907F82346686200EFEFF0 /* SuspendableTaskQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SuspendableTaskQueue.h; sourceTree = "<group>"; };
45FEA5CE156DDE8C00654101 /* Decimal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Decimal.h; sourceTree = "<group>"; };
460BB6131D0A1BEC00221812 /* Base64Utilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64Utilities.cpp; sourceTree = "<group>"; };
460BB6141D0A1BEC00221812 /* Base64Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64Utilities.h; sourceTree = "<group>"; };
@@ -25239,6 +25242,8 @@
F433E9021DBBDBA200EF0D14 /* StaticPasteboard.h */,
93B2D8150F9920D2006AE6B2 /* SuddenTermination.h */,
97627B9714FB5424002CDCA1 /* Supplementable.h */,
+ 466907F62346686200EFEFF0 /* SuspendableTaskQueue.cpp */,
+ 466907F82346686200EFEFF0 /* SuspendableTaskQueue.h */,
7CC564B618BABEA6001B9652 /* TelephoneNumberDetector.h */,
BCE65D310EAD1211007E4533 /* Theme.cpp */,
BCE658FE0EA9248A007E4533 /* Theme.h */,
@@ -31280,6 +31285,7 @@
97C078501165D5BE003A32EF /* SuffixTree.h in Headers */,
97627B9814FB5424002CDCA1 /* Supplementable.h in Headers */,
087558C613B4A57D00F49307 /* SurrogatePairAwareTextIterator.h in Headers */,
+ 46CDC1F023466B2300D2E70E /* SuspendableTaskQueue.h in Headers */,
62C1217D11AB9E77003C462C /* SuspendableTimer.h in Headers */,
B22279740D00BF220071B782 /* SVGAElement.h in Headers */,
24D912B113CA9A1F00D21915 /* SVGAltGlyphDefElement.h in Headers */,
Modified: branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.cpp (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.cpp 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.cpp 2021-04-28 18:12:18 UTC (rev 276724)
@@ -113,4 +113,9 @@
return !scriptExecutionContext() || scriptExecutionContext()->activeDOMObjectsAreStopped();
}
+bool ActiveDOMObject::isAllowedToRunScript() const
+{
+ return scriptExecutionContext() && !scriptExecutionContext()->activeDOMObjectsAreStopped() && !scriptExecutionContext()->activeDOMObjectsAreSuspended();
+}
+
} // namespace WebCore
Modified: branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.h (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.h 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/dom/ActiveDOMObject.h 2021-04-28 18:12:18 UTC (rev 276724)
@@ -113,6 +113,7 @@
}
bool isContextStopped() const;
+ bool isAllowedToRunScript() const;
protected:
explicit ActiveDOMObject(ScriptExecutionContext*);
Modified: branches/safari-607-branch/Source/WebCore/dom/ScriptExecutionContext.cpp (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/dom/ScriptExecutionContext.cpp 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/dom/ScriptExecutionContext.cpp 2021-04-28 18:12:18 UTC (rev 276724)
@@ -300,12 +300,13 @@
if (m_reasonForSuspendingActiveDOMObjects != why)
return;
- m_activeDOMObjectsAreSuspended = false;
forEachActiveDOMObject([](auto& activeDOMObject) {
activeDOMObject.resume();
return ShouldContinue::Yes;
});
+
+ m_activeDOMObjectsAreSuspended = false;
}
void ScriptExecutionContext::stopActiveDOMObjects()
Modified: branches/safari-607-branch/Source/WebCore/fileapi/FileReader.cpp (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/fileapi/FileReader.cpp 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/fileapi/FileReader.cpp 2021-04-28 18:12:18 UTC (rev 276724)
@@ -36,6 +36,7 @@
#include "Logging.h"
#include "ProgressEvent.h"
#include "ScriptExecutionContext.h"
+#include "SuspendableTaskQueue.h"
#include <_javascript_Core/ArrayBuffer.h>
#include <wtf/text/CString.h>
@@ -53,6 +54,7 @@
FileReader::FileReader(ScriptExecutionContext& context)
: ActiveDOMObject(&context)
+ , m_taskQueue(SuspendableTaskQueue::create(&context))
{
}
@@ -62,12 +64,6 @@
m_loader->cancel();
}
-bool FileReader::canSuspendForDocumentSuspension() const
-{
- // FIXME: It is not currently possible to suspend a FileReader, so pages with FileReader can not go into page cache.
- return false;
-}
-
const char* FileReader::activeDOMObjectName() const
{
return "FileReader";
@@ -82,6 +78,16 @@
m_state = DONE;
}
+bool FileReader::canSuspendForDocumentSuspension() const
+{
+ return true;
+}
+
+bool FileReader::hasPendingActivity() const
+{
+ return m_taskQueue->hasPendingTasks() || m_state == LOADING || ActiveDOMObject::hasPendingActivity();
+}
+
ExceptionOr<void> FileReader::readAsArrayBuffer(Blob* blob)
{
if (!blob)
@@ -129,8 +135,6 @@
if (m_state == LOADING)
return Exception { InvalidStateError };
- setPendingActivity(this);
-
m_blob = &blob;
m_readType = type;
m_state = LOADING;
@@ -153,7 +157,8 @@
m_aborting = true;
// Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stack.
- scriptExecutionContext()->postTask([this] (ScriptExecutionContext&) {
+ m_taskQueue->cancelAllTasks();
+ m_taskQueue->enqueueTask([this] {
ASSERT(m_state != DONE);
stop();
@@ -164,28 +169,29 @@
fireEvent(eventNames().errorEvent);
fireEvent(eventNames().abortEvent);
fireEvent(eventNames().loadendEvent);
-
- // All possible events have fired and we're done, no more pending activity.
- unsetPendingActivity(this);
});
}
void FileReader::didStartLoading()
{
- fireEvent(eventNames().loadstartEvent);
+ m_taskQueue->enqueueTask([this] {
+ fireEvent(eventNames().loadstartEvent);
+ });
}
void FileReader::didReceiveData()
{
- auto now = MonotonicTime::now();
- if (std::isnan(m_lastProgressNotificationTime)) {
- m_lastProgressNotificationTime = now;
- return;
- }
- if (now - m_lastProgressNotificationTime > progressNotificationInterval) {
- fireEvent(eventNames().progressEvent);
- m_lastProgressNotificationTime = now;
- }
+ m_taskQueue->enqueueTask([this] {
+ auto now = MonotonicTime::now();
+ if (std::isnan(m_lastProgressNotificationTime)) {
+ m_lastProgressNotificationTime = now;
+ return;
+ }
+ if (now - m_lastProgressNotificationTime > progressNotificationInterval) {
+ fireEvent(eventNames().progressEvent);
+ m_lastProgressNotificationTime = now;
+ }
+ });
}
void FileReader::didFinishLoading()
@@ -193,15 +199,14 @@
if (m_aborting)
return;
- ASSERT(m_state != DONE);
- m_state = DONE;
+ m_taskQueue->enqueueTask([this] {
+ ASSERT(m_state != DONE);
+ m_state = DONE;
- fireEvent(eventNames().progressEvent);
- fireEvent(eventNames().loadEvent);
- fireEvent(eventNames().loadendEvent);
-
- // All possible events have fired and we're done, no more pending activity.
- unsetPendingActivity(this);
+ fireEvent(eventNames().progressEvent);
+ fireEvent(eventNames().loadEvent);
+ fireEvent(eventNames().loadendEvent);
+ });
}
void FileReader::didFail(int errorCode)
@@ -210,19 +215,19 @@
if (m_aborting)
return;
- ASSERT(m_state != DONE);
- m_state = DONE;
+ m_taskQueue->enqueueTask([this, errorCode] {
+ ASSERT(m_state != DONE);
+ m_state = DONE;
- m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
- fireEvent(eventNames().errorEvent);
- fireEvent(eventNames().loadendEvent);
-
- // All possible events have fired and we're done, no more pending activity.
- unsetPendingActivity(this);
+ m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
+ fireEvent(eventNames().errorEvent);
+ fireEvent(eventNames().loadendEvent);
+ });
}
void FileReader::fireEvent(const AtomicString& type)
{
+ RELEASE_ASSERT(isAllowedToRunScript());
dispatchEvent(ProgressEvent::create(type, true, m_loader ? m_loader->bytesLoaded() : 0, m_loader ? m_loader->totalBytes() : 0));
}
Modified: branches/safari-607-branch/Source/WebCore/fileapi/FileReader.h (276723 => 276724)
--- branches/safari-607-branch/Source/WebCore/fileapi/FileReader.h 2021-04-28 18:07:17 UTC (rev 276723)
+++ branches/safari-607-branch/Source/WebCore/fileapi/FileReader.h 2021-04-28 18:12:18 UTC (rev 276724)
@@ -36,6 +36,7 @@
#include "FileError.h"
#include "FileReaderLoader.h"
#include "FileReaderLoaderClient.h"
+#include <wtf/UniqueRef.h>
namespace JSC {
class ArrayBuffer;
@@ -44,6 +45,7 @@
namespace WebCore {
class Blob;
+class SuspendableTaskQueue;
class FileReader final : public RefCounted<FileReader>, public ActiveDOMObject, public EventTargetWithInlineData, private FileReaderLoaderClient {
public:
@@ -73,6 +75,9 @@
using RefCounted::ref;
using RefCounted::deref;
+ // ActiveDOMObject
+ bool hasPendingActivity() const final;
+
private:
explicit FileReader(ScriptExecutionContext&);
@@ -102,6 +107,7 @@
std::unique_ptr<FileReaderLoader> m_loader;
RefPtr<FileError> m_error;
MonotonicTime m_lastProgressNotificationTime { MonotonicTime::nan() };
+ UniqueRef<SuspendableTaskQueue> m_taskQueue;
};
} // namespace WebCore
Added: branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.cpp (0 => 276724)
--- branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.cpp (rev 0)
+++ branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.cpp 2021-04-28 18:12:18 UTC (rev 276724)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SuspendableTaskQueue.h"
+
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+SuspendableTaskQueue::SuspendableTaskQueue(ScriptExecutionContext* context)
+ : ActiveDOMObject(context)
+ , m_taskQueue(context)
+ , m_isClosed(!context)
+{
+}
+
+SuspendableTaskQueue::~SuspendableTaskQueue() = default;
+
+void SuspendableTaskQueue::close()
+{
+ m_isClosed = true;
+ cancelAllTasks();
+}
+
+void SuspendableTaskQueue::cancelAllTasks()
+{
+ m_taskQueue.cancelAllTasks();
+ m_pendingTasks.clear();
+}
+
+void SuspendableTaskQueue::enqueueTask(TaskFunction&& task)
+{
+ if (m_isClosed)
+ return;
+
+ m_pendingTasks.append(WTFMove(task));
+
+ if (m_isSuspended)
+ return;
+
+ m_taskQueue.enqueueTask(std::bind(&SuspendableTaskQueue::runOneTask, this));
+}
+
+void SuspendableTaskQueue::runOneTask()
+{
+ ASSERT(!m_pendingTasks.isEmpty());
+ auto task = m_pendingTasks.takeFirst();
+ task();
+}
+
+const char* SuspendableTaskQueue::activeDOMObjectName() const
+{
+ return "SuspendableTaskQueue";
+}
+
+bool SuspendableTaskQueue::canSuspendForDocumentSuspension() const
+{
+ return true;
+}
+
+void SuspendableTaskQueue::stop()
+{
+ close();
+}
+
+void SuspendableTaskQueue::suspend(ReasonForSuspension)
+{
+ m_isSuspended = true;
+ m_taskQueue.cancelAllTasks();
+}
+
+void SuspendableTaskQueue::resume()
+{
+ m_isSuspended = false;
+ for (size_t i = 0; i < m_pendingTasks.size(); ++i)
+ m_taskQueue.enqueueTask(std::bind(&SuspendableTaskQueue::runOneTask, this));
+}
+
+} // namespace WebCore
Added: branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.h (0 => 276724)
--- branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.h (rev 0)
+++ branches/safari-607-branch/Source/WebCore/platform/SuspendableTaskQueue.h 2021-04-28 18:12:18 UTC (rev 276724)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ActiveDOMObject.h"
+#include "GenericTaskQueue.h"
+#include <wtf/UniqueRef.h>
+
+namespace WebCore {
+
+class SuspendableTaskQueue : public ActiveDOMObject {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static UniqueRef<SuspendableTaskQueue> create(ScriptExecutionContext* context)
+ {
+ auto taskQueue = makeUniqueRef<SuspendableTaskQueue>(context);
+ taskQueue->suspendIfNeeded();
+ return taskQueue;
+ }
+
+ ~SuspendableTaskQueue();
+
+ using TaskFunction = WTF::Function<void()>;
+ void enqueueTask(TaskFunction&&);
+ void cancelAllTasks();
+
+ void close();
+ bool isClosed() const { return m_isClosed; }
+
+ bool hasPendingTasks() const { return m_pendingTasks.isEmpty(); }
+
+private:
+ friend UniqueRef<SuspendableTaskQueue> WTF::makeUniqueRef<SuspendableTaskQueue, WebCore::ScriptExecutionContext*&>(WebCore::ScriptExecutionContext*&);
+
+ explicit SuspendableTaskQueue(ScriptExecutionContext*);
+
+ void runOneTask();
+
+ // ActiveDOMObject.
+ const char* activeDOMObjectName() const final;
+ bool canSuspendForDocumentSuspension() const final;
+ void stop() final;
+ void suspend(ReasonForSuspension) final;
+ void resume() final;
+
+ GenericTaskQueue<ScriptExecutionContext> m_taskQueue;
+ Deque<TaskFunction> m_pendingTasks;
+ bool m_isClosed { false };
+ bool m_isSuspended { false };
+};
+
+} // namespace WebCore