Title: [286414] trunk
Revision
286414
Author
[email protected]
Date
2021-12-01 22:27:47 -0800 (Wed, 01 Dec 2021)

Log Message

FileSystemSyncAccessHandle should be invalidated when network process crashes
https://bugs.webkit.org/show_bug.cgi?id=232605
<rdar://problem/85187706>

Reviewed by Youenn Fablet.

Source/WebCore:

Make FileSystemStorageConnection keep track of FileSystemSyncAccessHandle. When connection is closed, or access
handle is explicitly invalidated (for example, due to file deletion in the backend), FileSystemStorageConnection
will invalidate FileSystemSyncAccessHandle.

Normally, to close a FileSystemSyncAccessHandle (when close() is called or context stops), we need to:
1. close file descriptor (FileSystemSyncAccessHandle::closeFile)
2. notify backend about close (FileSystemSyncAccessHandle::closeBackend)
3. get close result and complete callbacks (FileSystemSyncAccessHandle::didCloseBackend)
For invalidation case, we only need to perform step 1 and 3 because connection to backend is lost or backend
initiates the close.

API test: FileSystemAccess.NetworkProcessCrashDuringWrite

* Headers.cmake:
* Modules/cache/WindowOrWorkerGlobalScopeCaches.cpp:
* Modules/filesystemaccess/FileSystemFileHandle.cpp:
(WebCore::FileSystemFileHandle::registerSyncAccessHandle):
(WebCore::FileSystemFileHandle::unregisterSyncAccessHandle):
* Modules/filesystemaccess/FileSystemFileHandle.h:
* Modules/filesystemaccess/FileSystemStorageConnection.h:
(WebCore::FileSystemStorageConnection::isWorker const):
* Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
(WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::closeInternal):
(WebCore::FileSystemSyncAccessHandle::closeFile):
(WebCore::FileSystemSyncAccessHandle::didCloseFile):
(WebCore::FileSystemSyncAccessHandle::closeBackend):
(WebCore::FileSystemSyncAccessHandle::didCloseBackend):
(WebCore::FileSystemSyncAccessHandle::invalidate):
(WebCore::FileSystemSyncAccessHandle::didClose): Deleted.
* Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
* Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp:
(WebCore::WorkerFileSystemStorageConnection::connectionClosed):
(WebCore::WorkerFileSystemStorageConnection::registerSyncAccessHandle):
(WebCore::WorkerFileSystemStorageConnection::unregisterSyncAccessHandle):
(WebCore::WorkerFileSystemStorageConnection::invalidateAccessHandle):
* Modules/filesystemaccess/WorkerFileSystemStorageConnection.h:
(isType):
* Modules/mediastream/RTCRtpScriptTransformer.cpp:
* WebCore.xcodeproj/project.pbxproj:
* dom/BroadcastChannel.cpp:
* workers/WorkerGlobalScope.cpp:
* workers/WorkerGlobalScope.h:
* workers/WorkerOrWorkletScriptController.cpp:

Source/WebKit:

* WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp:
(WebKit::WebFileSystemStorageConnection::connectionClosed):
(WebKit::WebFileSystemStorageConnection::registerSyncAccessHandle):
(WebKit::WebFileSystemStorageConnection::unregisterSyncAccessHandle):
(WebKit::WebFileSystemStorageConnection::invalidateAccessHandle):
* WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm:
(test):
(keepAccessHandleActive):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286413 => 286414)


--- trunk/Source/WebCore/ChangeLog	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/ChangeLog	2021-12-02 06:27:47 UTC (rev 286414)
@@ -1,3 +1,57 @@
+2021-12-01  Sihui Liu  <[email protected]>
+
+        FileSystemSyncAccessHandle should be invalidated when network process crashes
+        https://bugs.webkit.org/show_bug.cgi?id=232605
+        <rdar://problem/85187706>
+
+        Reviewed by Youenn Fablet.
+
+        Make FileSystemStorageConnection keep track of FileSystemSyncAccessHandle. When connection is closed, or access 
+        handle is explicitly invalidated (for example, due to file deletion in the backend), FileSystemStorageConnection
+        will invalidate FileSystemSyncAccessHandle.
+
+        Normally, to close a FileSystemSyncAccessHandle (when close() is called or context stops), we need to: 
+        1. close file descriptor (FileSystemSyncAccessHandle::closeFile)
+        2. notify backend about close (FileSystemSyncAccessHandle::closeBackend)
+        3. get close result and complete callbacks (FileSystemSyncAccessHandle::didCloseBackend)
+        For invalidation case, we only need to perform step 1 and 3 because connection to backend is lost or backend
+        initiates the close.
+
+        API test: FileSystemAccess.NetworkProcessCrashDuringWrite
+
+        * Headers.cmake:
+        * Modules/cache/WindowOrWorkerGlobalScopeCaches.cpp:
+        * Modules/filesystemaccess/FileSystemFileHandle.cpp:
+        (WebCore::FileSystemFileHandle::registerSyncAccessHandle):
+        (WebCore::FileSystemFileHandle::unregisterSyncAccessHandle):
+        * Modules/filesystemaccess/FileSystemFileHandle.h:
+        * Modules/filesystemaccess/FileSystemStorageConnection.h:
+        (WebCore::FileSystemStorageConnection::isWorker const):
+        * Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
+        (WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
+        (WebCore::FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle):
+        (WebCore::FileSystemSyncAccessHandle::closeInternal):
+        (WebCore::FileSystemSyncAccessHandle::closeFile):
+        (WebCore::FileSystemSyncAccessHandle::didCloseFile):
+        (WebCore::FileSystemSyncAccessHandle::closeBackend):
+        (WebCore::FileSystemSyncAccessHandle::didCloseBackend):
+        (WebCore::FileSystemSyncAccessHandle::invalidate):
+        (WebCore::FileSystemSyncAccessHandle::didClose): Deleted.
+        * Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
+        * Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp:
+        (WebCore::WorkerFileSystemStorageConnection::connectionClosed):
+        (WebCore::WorkerFileSystemStorageConnection::registerSyncAccessHandle):
+        (WebCore::WorkerFileSystemStorageConnection::unregisterSyncAccessHandle):
+        (WebCore::WorkerFileSystemStorageConnection::invalidateAccessHandle):
+        * Modules/filesystemaccess/WorkerFileSystemStorageConnection.h:
+        (isType):
+        * Modules/mediastream/RTCRtpScriptTransformer.cpp:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/BroadcastChannel.cpp:
+        * workers/WorkerGlobalScope.cpp:
+        * workers/WorkerGlobalScope.h:
+        * workers/WorkerOrWorkletScriptController.cpp:
+
 2021-12-01  Chris Dumez  <[email protected]>
 
         validity.valueMissing should not rely on element's disabled state for inputs of type radio/file/checkbox

Modified: trunk/Source/WebCore/Headers.cmake (286413 => 286414)


--- trunk/Source/WebCore/Headers.cmake	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Headers.cmake	2021-12-02 06:27:47 UTC (rev 286414)
@@ -1885,7 +1885,10 @@
     workers/WorkerAnimationController.h
     workers/WorkerDebuggerProxy.h
     workers/WorkerFontLoadRequest.h
+    workers/WorkerGlobalScope.h
     workers/WorkerLoaderProxy.h
+    workers/WorkerOrWorkletGlobalScope.h
+    workers/WorkerOrWorkletScriptController.h
     workers/WorkerOrWorkletThread.h
     workers/WorkerRunLoop.h
     workers/WorkerScriptLoader.h

Modified: trunk/Source/WebCore/Modules/cache/WindowOrWorkerGlobalScopeCaches.cpp (286413 => 286414)


--- trunk/Source/WebCore/Modules/cache/WindowOrWorkerGlobalScopeCaches.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/cache/WindowOrWorkerGlobalScopeCaches.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -34,6 +34,7 @@
 #include "Frame.h"
 #include "Page.h"
 #include "Supplementable.h"
+#include "WorkerCacheStorageConnection.h"
 #include "WorkerGlobalScope.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -32,6 +32,7 @@
 #include "JSDOMPromiseDeferred.h"
 #include "JSFile.h"
 #include "JSFileSystemSyncAccessHandle.h"
+#include "WorkerFileSystemStorageConnection.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -97,5 +98,21 @@
     connection().close(identifier(), accessHandleIdentifier, WTFMove(completionHandler));
 }
 
+void FileSystemFileHandle::registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier identifier, FileSystemSyncAccessHandle& handle)
+{
+    if (isClosed())
+        return;
+
+    downcast<WorkerFileSystemStorageConnection>(connection()).registerSyncAccessHandle(identifier, handle);
+}
+
+void FileSystemFileHandle::unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier identifier)
+{
+    if (isClosed())
+        return;
+
+    connection().unregisterSyncAccessHandle(identifier);
+}
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -42,6 +42,8 @@
 
     void createSyncAccessHandle(DOMPromiseDeferred<IDLInterface<FileSystemSyncAccessHandle>>&&);
     void close(FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&&);
+    void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, FileSystemSyncAccessHandle&);
+    void unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier);
 
 private:
     FileSystemFileHandle(ScriptExecutionContext&, String&&, FileSystemHandleIdentifier, Ref<FileSystemStorageConnection>&&);

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -27,6 +27,7 @@
 
 #include "FileSystemHandleIdentifier.h"
 #include "FileSystemSyncAccessHandleIdentifier.h"
+#include "ScriptExecutionContextIdentifier.h"
 #include <wtf/CompletionHandler.h>
 #include <wtf/FileSystem.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -35,6 +36,7 @@
 
 class FileSystemDirectoryHandle;
 class FileSystemFileHandle;
+class FileSystemSyncAccessHandle;
 template<typename> class ExceptionOr;
 
 class FileSystemStorageConnection : public ThreadSafeRefCounted<FileSystemStorageConnection> {
@@ -50,6 +52,7 @@
     using GetHandleWithTypeCallback = CompletionHandler<void(ExceptionOr<std::pair<FileSystemHandleIdentifier, bool>>&&)>;
     using StringCallback = CompletionHandler<void(ExceptionOr<String>&&)>;
 
+    virtual bool isWorker() const { return false; }
     virtual void closeHandle(FileSystemHandleIdentifier) = 0;
     virtual void isSameEntry(FileSystemHandleIdentifier, FileSystemHandleIdentifier, SameEntryCallback&&) = 0;
     virtual void move(FileSystemHandleIdentifier, FileSystemHandleIdentifier, const String& newName, VoidCallback&&) = 0;
@@ -60,6 +63,9 @@
     virtual void getFile(FileSystemHandleIdentifier, StringCallback&&) = 0;
     virtual void createSyncAccessHandle(FileSystemHandleIdentifier, GetAccessHandleCallback&&) = 0;
     virtual void close(FileSystemHandleIdentifier, FileSystemSyncAccessHandleIdentifier, VoidCallback&&) = 0;
+    virtual void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, ScriptExecutionContextIdentifier) = 0;
+    virtual void unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier) = 0;
+    virtual void invalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier) = 0;
     virtual void getHandleNames(FileSystemHandleIdentifier, GetHandleNamesCallback&&) = 0;
     virtual void getHandle(FileSystemHandleIdentifier, const String& name, GetHandleWithTypeCallback&&) = 0;
 };

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -30,6 +30,7 @@
 #include "FileSystemFileHandle.h"
 #include "JSDOMPromiseDeferred.h"
 #include "WorkerGlobalScope.h"
+#include "WorkerThread.h"
 #include <wtf/CompletionHandler.h>
 
 namespace WebCore {
@@ -47,11 +48,16 @@
 {
     ASSERT(m_file != FileSystem::invalidPlatformFileHandle);
     suspendIfNeeded();
+
+    m_source->registerSyncAccessHandle(m_identifier, *this);
 }
 
 FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle()
 {
     ASSERT(isClosingOrClosed());
+
+    m_source->unregisterSyncAccessHandle(m_identifier);
+
     if (m_closeResult)
         return;
 
@@ -142,35 +148,52 @@
     if (isClosing)
         return;
 
+    ASSERT(m_file != FileSystem::invalidPlatformFileHandle);
+    closeFile();
+}
+
+void FileSystemSyncAccessHandle::closeFile()
+{
+    if (m_file == FileSystem::invalidPlatformFileHandle)
+        return;
+
     auto* scope = downcast<WorkerGlobalScope>(scriptExecutionContext());
     ASSERT(scope);
 
-    ASSERT(m_file != FileSystem::invalidPlatformFileHandle);
     WorkerGlobalScope::postFileSystemStorageTask([weakThis = WeakPtr { *this }, file = std::exchange(m_file, FileSystem::invalidPlatformFileHandle), workerThread = Ref { scope->thread() }]() mutable {
         FileSystem::closeFile(file);
         workerThread->runLoop().postTask([weakThis = WTFMove(weakThis)](auto&) mutable {
             if (weakThis)
-                weakThis->closeBackend(CloseMode::Async);
+                weakThis->didCloseFile();
         });
     });
 }
 
+void FileSystemSyncAccessHandle::didCloseFile()
+{
+    closeBackend(CloseMode::Async);
+}
+
 void FileSystemSyncAccessHandle::closeBackend(CloseMode mode)
 {
+    if (m_closeResult)
+        return;
+
     if (mode == CloseMode::Async) {
         m_source->close(m_identifier, [this, protectedThis = Ref { *this }](auto result) mutable {
-            didClose(WTFMove(result));
+            didCloseBackend(WTFMove(result));
         });
         return;
     }
 
     m_source->close(m_identifier, [](auto) { });
-    didClose({ });
+    didCloseBackend({ });
 }
 
-void FileSystemSyncAccessHandle::didClose(ExceptionOr<void>&& result)
+void FileSystemSyncAccessHandle::didCloseBackend(ExceptionOr<void>&& result)
 {
-    ASSERT(!m_closeResult);
+    if (m_closeResult)
+        return;
 
     m_closeResult = WTFMove(result);
     auto callbacks = std::exchange(m_closeCallbacks, { });
@@ -247,4 +270,12 @@
     closeInternal([](auto) { });
 }
 
+void FileSystemSyncAccessHandle::invalidate()
+{
+    closeFile();
+
+    // Invalidation is initiated by backend.
+    didCloseBackend({ });
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -52,11 +52,11 @@
     void getSize(DOMPromiseDeferred<IDLUnsignedLongLong>&&);
     void flush(DOMPromiseDeferred<void>&&);
     void close(DOMPromiseDeferred<void>&&);
-    void didClose(ExceptionOr<void>&&);
     ExceptionOr<unsigned long long> read(BufferSource&&, FilesystemReadWriteOptions);
     ExceptionOr<unsigned long long> write(BufferSource&&, FilesystemReadWriteOptions);
     using Result = std::variant<ExceptionOr<void>, ExceptionOr<uint64_t>>;
     void completePromise(Result&&);
+    void invalidate();
 
 private:
     FileSystemSyncAccessHandle(ScriptExecutionContext&, FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle);
@@ -63,8 +63,11 @@
     bool isClosingOrClosed() const;
     using CloseCallback = CompletionHandler<void(ExceptionOr<void>&&)>;
     void closeInternal(CloseCallback&&);
+    void closeFile();
+    void didCloseFile();
     enum class CloseMode : bool { Async, Sync };
     void closeBackend(CloseMode);
+    void didCloseBackend(ExceptionOr<void>&&);
 
     // ActiveDOMObject
     const char* activeDOMObjectName() const final;

Modified: trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -52,6 +52,9 @@
 
 void WorkerFileSystemStorageConnection::connectionClosed()
 {
+    for (auto handle : m_syncAccessHandles.values())
+        handle->invalidate();
+
     scopeClosed();
 }
 
@@ -287,6 +290,31 @@
     });
 }
 
+void WorkerFileSystemStorageConnection::registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier identifier, FileSystemSyncAccessHandle& handle)
+{
+    if (!m_scope)
+        return;
+
+    m_syncAccessHandles.add(identifier, WeakPtr { handle });
+    callOnMainThread([identifier, contextIdentifier = m_scope->identifier(), mainThreadConnection = m_mainThreadConnection]() mutable {
+        mainThreadConnection->registerSyncAccessHandle(identifier, contextIdentifier);
+    });
+}
+
+void WorkerFileSystemStorageConnection::unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier identifier)
+{
+    m_syncAccessHandles.remove(identifier);
+    callOnMainThread([identifier, mainThreadConnection = m_mainThreadConnection]() mutable {
+        mainThreadConnection->unregisterSyncAccessHandle(identifier);
+    });
+}
+
+void WorkerFileSystemStorageConnection::invalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier identifier)
+{
+    if (auto handle = m_syncAccessHandles.get(identifier))
+        handle->invalidate();
+}
+
 void WorkerFileSystemStorageConnection::getHandleNames(FileSystemHandleIdentifier identifier, GetHandleNamesCallback&& callback)
 {
     if (!m_scope)

Modified: trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h (286413 => 286414)


--- trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -43,6 +43,7 @@
     FileSystemStorageConnection* mainThreadConnection() const { return m_mainThreadConnection.get(); }
     void connectionClosed();
     void scopeClosed();
+    void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, FileSystemSyncAccessHandle&);
     using CallbackIdentifier = WorkerFileSystemStorageConnectionCallbackIdentifier;
     void didIsSameEntry(CallbackIdentifier, ExceptionOr<bool>&&);
     void didGetHandle(CallbackIdentifier, ExceptionOr<FileSystemHandleIdentifier>&&);
@@ -57,6 +58,7 @@
     WorkerFileSystemStorageConnection(WorkerGlobalScope&, Ref<FileSystemStorageConnection>&&);
 
     // FileSystemStorageConnection
+    bool isWorker() const final { return true; }
     void closeHandle(FileSystemHandleIdentifier) final;
     void isSameEntry(FileSystemHandleIdentifier, FileSystemHandleIdentifier, FileSystemStorageConnection::SameEntryCallback&&) final;
     void move(FileSystemHandleIdentifier, FileSystemHandleIdentifier, const String& newName, VoidCallback&&) final;
@@ -67,9 +69,11 @@
     void getHandleNames(FileSystemHandleIdentifier, GetHandleNamesCallback&&) final;
     void getHandle(FileSystemHandleIdentifier, const String& name, GetHandleWithTypeCallback&&) final;
     void getFile(FileSystemHandleIdentifier, StringCallback&&) final;
-
     void createSyncAccessHandle(FileSystemHandleIdentifier, FileSystemStorageConnection::GetAccessHandleCallback&&) final;
     void close(FileSystemHandleIdentifier, FileSystemSyncAccessHandleIdentifier, FileSystemStorageConnection::VoidCallback&&) final;
+    void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, ScriptExecutionContextIdentifier) final { };
+    void unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier) final;
+    void invalidateAccessHandle(FileSystemSyncAccessHandleIdentifier) final;
 
     WeakPtr<WorkerGlobalScope> m_scope;
     RefPtr<FileSystemStorageConnection> m_mainThreadConnection;
@@ -81,6 +85,12 @@
     HashMap<CallbackIdentifier, FileSystemStorageConnection::GetHandleNamesCallback> m_getHandleNamesCallbacks;
     HashMap<CallbackIdentifier, FileSystemStorageConnection::GetHandleWithTypeCallback> m_getHandleWithTypeCallbacks;
     HashMap<CallbackIdentifier, FileSystemStorageConnection::StringCallback> m_stringCallbacks;
+    HashMap<FileSystemSyncAccessHandleIdentifier, Function<void()>> m_accessHandleInvalidationHandlers;
+    HashMap<FileSystemSyncAccessHandleIdentifier, WeakPtr<FileSystemSyncAccessHandle>> m_syncAccessHandles;
 };
 
 } // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WorkerFileSystemStorageConnection)
+    static bool isType(const WebCore::FileSystemStorageConnection& connection) { return connection.isWorker(); }
+SPECIALIZE_TYPE_TRAITS_END()

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp (286413 => 286414)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -36,6 +36,7 @@
 #include "ReadableStream.h"
 #include "ReadableStreamSource.h"
 #include "SerializedScriptValue.h"
+#include "WorkerThread.h"
 #include "WritableStream.h"
 #include "WritableStreamSink.h"
 

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (286413 => 286414)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-12-02 06:27:47 UTC (rev 286414)
@@ -2659,7 +2659,7 @@
 		838F86DB1F509E7B00E8CFC5 /* FileSystemEntryCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 838F86D71F509E6C00E8CFC5 /* FileSystemEntryCallback.h */; };
 		8399470C1F50B63E00E9D86B /* DOMFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 839947071F50B63800E9D86B /* DOMFileSystem.h */; };
 		839947101F50B6FA00E9D86B /* JSDOMFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 8399470E1F50B6F300E9D86B /* JSDOMFileSystem.h */; };
-		839A095D2524F37F00EEF328 /* WorkerOrWorkletScriptController.h in Headers */ = {isa = PBXBuildFile; fileRef = 839A095B2524F37600EEF328 /* WorkerOrWorkletScriptController.h */; };
+		839A095D2524F37F00EEF328 /* WorkerOrWorkletScriptController.h in Headers */ = {isa = PBXBuildFile; fileRef = 839A095B2524F37600EEF328 /* WorkerOrWorkletScriptController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		839A2F2E1E204A710039057E /* WebGLStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 839A2F2C1E204A6D0039057E /* WebGLStateTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		839AAFED1A0C0C8D00605F99 /* HTMLWBRElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 839AAFEB1A0C0C8D00605F99 /* HTMLWBRElement.h */; };
 		839BE6D524F58762004DF50F /* IIRFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 839BE6D224F58755004DF50F /* IIRFilter.h */; };
@@ -2687,7 +2687,7 @@
 		83D35AEC1C7187FA00F70D5A /* XMLHttpRequestEventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */; };
 		83D35AF21C718D9000F70D5A /* JSXMLHttpRequestEventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D35AF01C718D8400F70D5A /* JSXMLHttpRequestEventTarget.h */; };
 		83D511F6250C1CBF002EDC51 /* PushPullFIFO.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D511F5250C1CA8002EDC51 /* PushPullFIFO.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		83D6AAE62524EE1C00428B4B /* WorkerOrWorkletGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D6AAE42524EE1300428B4B /* WorkerOrWorkletGlobalScope.h */; };
+		83D6AAE62524EE1C00428B4B /* WorkerOrWorkletGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D6AAE42524EE1300428B4B /* WorkerOrWorkletGlobalScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		83DB9E0F24DA19490037B468 /* BiquadFilterType.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DB9E0C24DA18B50037B468 /* BiquadFilterType.h */; };
 		83DB9E1024DA19570037B468 /* BiquadFilterOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DB9E0E24DA18B60037B468 /* BiquadFilterOptions.h */; };
 		83E359A21BB1031D002CEB98 /* JSHTMLTimeElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E359A01BB1031D002CEB98 /* JSHTMLTimeElement.h */; };

Modified: trunk/Source/WebCore/dom/BroadcastChannel.cpp (286413 => 286414)


--- trunk/Source/WebCore/dom/BroadcastChannel.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/dom/BroadcastChannel.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -34,6 +34,7 @@
 #include "SerializedScriptValue.h"
 #include "WorkerGlobalScope.h"
 #include "WorkerLoaderProxy.h"
+#include "WorkerThread.h"
 #include <wtf/CallbackAggregator.h>
 #include <wtf/HashMap.h>
 #include <wtf/IsoMallocInlines.h>

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (286413 => 286414)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -50,16 +50,20 @@
 #include "SecurityOriginPolicy.h"
 #include "ServiceWorkerGlobalScope.h"
 #include "SocketProvider.h"
+#include "WorkerCacheStorageConnection.h"
 #include "WorkerFileSystemStorageConnection.h"
 #include "WorkerFontLoadRequest.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerLocation.h"
+#include "WorkerMessagePortChannelProvider.h"
 #include "WorkerMessagingProxy.h"
 #include "WorkerNavigator.h"
+#include "WorkerOrWorkletGlobalScope.h"
 #include "WorkerReportingProxy.h"
 #include "WorkerSWClientConnection.h"
 #include "WorkerScriptLoader.h"
 #include "WorkerStorageConnection.h"
+#include "WorkerThread.h"
 #include <_javascript_Core/ScriptArguments.h>
 #include <_javascript_Core/ScriptCallStack.h>
 #include <wtf/IsoMallocInlines.h>

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (286413 => 286414)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -29,15 +29,12 @@
 #include "Base64Utilities.h"
 #include "CacheStorageConnection.h"
 #include "ImageBitmap.h"
-#include "ScriptBufferSourceProvider.h"
 #include "ScriptExecutionContext.h"
 #include "Supplementable.h"
 #include "WindowOrWorkerGlobalScope.h"
 #include "WorkerOrWorkletGlobalScope.h"
 #include "WorkerOrWorkletScriptController.h"
-#include "WorkerCacheStorageConnection.h"
-#include "WorkerMessagePortChannelProvider.h"
-#include "WorkerThread.h"
+#include "WorkerType.h"
 #include <_javascript_Core/ConsoleMessage.h>
 #include <memory>
 #include <wtf/HashMap.h>
@@ -54,14 +51,20 @@
 class Crypto;
 class FileSystemStorageConnection;
 class FontFaceSet;
+class MessagePortChannelProvider;
 class Performance;
 class ScheduledAction;
+class ScriptBuffer;
+class ScriptBufferSourceProvider;
+class WorkerCacheStorageConnection;
 class WorkerFileSystemStorageConnection;
 class WorkerLocation;
+class WorkerMessagePortChannelProvider;
 class WorkerNavigator;
 class WorkerSWClientConnection;
 class WorkerStorageConnection;
 class WorkerStorageConnection;
+class WorkerThread;
 struct WorkerParameters;
 
 namespace IDBClient {
@@ -90,7 +93,7 @@
     WorkerStorageConnection& storageConnection();
     static void postFileSystemStorageTask(Function<void()>&&);
     WorkerFileSystemStorageConnection& getFileSystemStorageConnection(Ref<FileSystemStorageConnection>&&);
-    WorkerFileSystemStorageConnection* fileSystemStorageConnection();
+    WEBCORE_EXPORT WorkerFileSystemStorageConnection* fileSystemStorageConnection();
     WorkerCacheStorageConnection& cacheStorageConnection();
     MessagePortChannelProvider& messagePortChannelProvider();
 #if ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp (286413 => 286414)


--- trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -43,6 +43,8 @@
 #include "WebCoreJSClientData.h"
 #include "WorkerConsoleClient.h"
 #include "WorkerModuleScriptLoader.h"
+#include "WorkerOrWorkletThread.h"
+#include "WorkerRunLoop.h"
 #include "WorkerScriptFetcher.h"
 #include <_javascript_Core/Completion.h>
 #include <_javascript_Core/DeferTermination.h>

Modified: trunk/Source/WebKit/ChangeLog (286413 => 286414)


--- trunk/Source/WebKit/ChangeLog	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebKit/ChangeLog	2021-12-02 06:27:47 UTC (rev 286414)
@@ -1,3 +1,18 @@
+2021-12-01  Sihui Liu  <[email protected]>
+
+        FileSystemSyncAccessHandle should be invalidated when network process crashes
+        https://bugs.webkit.org/show_bug.cgi?id=232605
+        <rdar://problem/85187706>
+
+        Reviewed by Youenn Fablet.
+
+        * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp:
+        (WebKit::WebFileSystemStorageConnection::connectionClosed):
+        (WebKit::WebFileSystemStorageConnection::registerSyncAccessHandle):
+        (WebKit::WebFileSystemStorageConnection::unregisterSyncAccessHandle):
+        (WebKit::WebFileSystemStorageConnection::invalidateAccessHandle):
+        * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h:
+
 2021-12-01  Jean-Yves Avenard  <[email protected]>
 
         Avoid allocating and copy memory from a SharedMemory into a SharedBuffer

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp (286413 => 286414)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp	2021-12-02 06:27:47 UTC (rev 286414)
@@ -30,6 +30,9 @@
 #include <WebCore/ExceptionOr.h>
 #include <WebCore/FileSystemDirectoryHandle.h>
 #include <WebCore/FileSystemFileHandle.h>
+#include <WebCore/ScriptExecutionContext.h>
+#include <WebCore/WorkerFileSystemStorageConnection.h>
+#include <WebCore/WorkerGlobalScope.h>
 
 namespace WebKit {
 
@@ -46,6 +49,9 @@
 void WebFileSystemStorageConnection::connectionClosed()
 {
     m_connection = nullptr;
+
+    for (auto identifier : m_syncAccessHandles.keys())
+        invalidateAccessHandle(identifier);
 }
 
 void WebFileSystemStorageConnection::closeHandle(WebCore::FileSystemHandleIdentifier identifier)
@@ -193,4 +199,24 @@
     });
 }
 
+void WebFileSystemStorageConnection::registerSyncAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier identifier, WebCore::ScriptExecutionContextIdentifier contextIdentifier)
+{
+    m_syncAccessHandles.add(identifier, contextIdentifier);
+}
+
+void WebFileSystemStorageConnection::unregisterSyncAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier identifier)
+{
+    m_syncAccessHandles.remove(identifier);
+}
+
+void WebFileSystemStorageConnection::invalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier identifier)
+{
+    if (auto contextIdentifier = m_syncAccessHandles.get(identifier)) {
+        WebCore::ScriptExecutionContext::postTaskTo(contextIdentifier, [identifier](auto& context) mutable {
+            if (FileSystemStorageConnection* connection = downcast<WebCore::WorkerGlobalScope>(context).fileSystemStorageConnection())
+                connection->invalidateAccessHandle(identifier);
+        });
+    }
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h (286413 => 286414)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h	2021-12-02 06:27:47 UTC (rev 286414)
@@ -67,6 +67,7 @@
 public:
     static Ref<WebFileSystemStorageConnection> create(IPC::Connection&);
     void connectionClosed();
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
 
 private:
     explicit WebFileSystemStorageConnection(IPC::Connection&);
@@ -85,7 +86,11 @@
 
     void createSyncAccessHandle(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemStorageConnection::GetAccessHandleCallback&&) final;
     void close(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemSyncAccessHandleIdentifier, WebCore::FileSystemStorageConnection::VoidCallback&&) final;
+    void registerSyncAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier, WebCore::ScriptExecutionContextIdentifier) final;
+    void unregisterSyncAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier) final;
+    void invalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier) final;
 
+    HashMap<WebCore::FileSystemSyncAccessHandleIdentifier, WebCore::ScriptExecutionContextIdentifier> m_syncAccessHandles;
     RefPtr<IPC::Connection> m_connection;
 };
 

Modified: trunk/Tools/ChangeLog (286413 => 286414)


--- trunk/Tools/ChangeLog	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Tools/ChangeLog	2021-12-02 06:27:47 UTC (rev 286414)
@@ -1,3 +1,15 @@
+2021-12-01  Sihui Liu  <[email protected]>
+
+        FileSystemSyncAccessHandle should be invalidated when network process crashes
+        https://bugs.webkit.org/show_bug.cgi?id=232605
+        <rdar://problem/85187706>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm:
+        (test):
+        (keepAccessHandleActive):
+
 2021-12-01  Carlos Alberto Lopez Perez  <[email protected]>
 
         [EWS][GTK][WPE] Add a new Class for running layout tests on the EWS for the GTK and WPE ports.

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm (286413 => 286414)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	2021-12-02 06:05:10 UTC (rev 286413)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	2021-12-02 06:27:47 UTC (rev 286414)
@@ -59,15 +59,30 @@
     </script>";
 
 static const char* workerBytes = R"TESTRESOURCE(
+var position = 0;
+var accessHandle;
 async function test()
 {
     try {
         var rootHandle = await navigator.storage.getDirectory();
         var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : true });
-        var accessHandle = await fileHandle.createSyncAccessHandle();
+        accessHandle = await fileHandle.createSyncAccessHandle();
         var buffer = new ArrayBuffer(10);
         var writeSize = accessHandle.write(buffer, { "at" : 0 });
         self.postMessage('success: write ' + writeSize + ' bytes');
+        keepAccessHandleActive();
+    } catch(err) {
+        self.postMessage('error: ' + err.name + ' - ' + err.message);
+        close();
+    }
+}
+function keepAccessHandleActive()
+{
+    try {
+        var buffer = new ArrayBuffer(1);
+        var writeSize = accessHandle.write(buffer, { "at" : position });
+        position += writeSize;
+        setTimeout(keepAccessHandleActive, 100);
     } catch (err) {
         self.postMessage('error: ' + err.name + ' - ' + err.message);
         close();
@@ -76,7 +91,7 @@
 test();
 )TESTRESOURCE";
 
-TEST(FileSystemAccess, ProcessCrashDuringWrite)
+TEST(FileSystemAccess, WebProcessCrashDuringWrite)
 {
     auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -130,6 +145,53 @@
     EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
 }
 
+TEST(FileSystemAccess, NetworkProcessCrashDuringWrite)
+{
+    auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    auto preferences = [configuration preferences];
+    preferences._fileSystemAccessEnabled = YES;
+    preferences._accessHandleEnabled = YES;
+    preferences._storageAPIEnabled = YES;
+    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
+    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
+        RetainPtr<NSData> data;
+        NSURL *requestURL = task.request.URL;
+        EXPECT_WK_STREQ("webkit://webkit.org/worker.js", requestURL.absoluteString);
+        auto response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/_javascript_" expectedContentLength:0 textEncodingName:nil]);
+        data = "" dataWithBytes:workerBytes length:strlen(workerBytes)];
+        [task didReceiveResponse:response.get()];
+        [task didReceiveData:data.get()];
+        [task didFinish];
+    }];
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webkit"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
+
+    [webView evaluateJavaScript:@"start()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
+
+    // Kill network process.
+    [[configuration websiteDataStore] _terminateNetworkProcess];
+
+    // Open access handle should be closed when network process crashes.
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"error: InvalidStateError - AccessHandle is closing or closed", [lastScriptMessage body]);
+
+    // Access handle can be created after network process is relaunched.
+    [webView evaluateJavaScript:@"start()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
+}
+
 static NSString *basicString = @"<script> \
     async function open() \
     { \
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to