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

Changeset 284652 in webkit


Ignore:
Timestamp:
Oct 21, 2021, 4:13:02 PM (5 years ago)
Author:
sihui_liu@apple.com
Message:

FileSystemSyncAccessHandle should close platform file handle on close()
https://bugs.webkit.org/show_bug.cgi?id=232067
<rdar://problem/84517013>

Reviewed by Youenn Fablet.

LayoutTests/imported/w3c:

  • web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt:

Source/WebCore:

This patch also ensures no request is sent after close() is called.

Test: storage/filesystemaccess/sync-access-handle-close-worker.html

  • Modules/filesystemaccess/FileSystemFileHandle.cpp:

(WebCore::FileSystemFileHandle::createSyncAccessHandle):

  • Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:

(WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::isClosingOrClosed const):
(WebCore::FileSystemSyncAccessHandle::truncate):
(WebCore::FileSystemSyncAccessHandle::getSize):
(WebCore::FileSystemSyncAccessHandle::flush):
(WebCore::FileSystemSyncAccessHandle::close):
(WebCore::FileSystemSyncAccessHandle::didClose):
(WebCore::FileSystemSyncAccessHandle::read):
(WebCore::FileSystemSyncAccessHandle::write):

  • Modules/filesystemaccess/FileSystemSyncAccessHandle.h:

LayoutTests:

  • storage/filesystemaccess/resources/sync-access-handle-close.js: Added.

(finishTest):
(async testFunctions):
(async test):

  • storage/filesystemaccess/sync-access-handle-close-worker-expected.txt: Added.
  • storage/filesystemaccess/sync-access-handle-close-worker.html: Added.
Location:
trunk
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r284648 r284652  
     12021-10-21  Sihui Liu  <sihui_liu@apple.com>
     2
     3        FileSystemSyncAccessHandle should close platform file handle on close()
     4        https://bugs.webkit.org/show_bug.cgi?id=232067
     5        <rdar://problem/84517013>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        * storage/filesystemaccess/resources/sync-access-handle-close.js: Added.
     10        (finishTest):
     11        (async testFunctions):
     12        (async test):
     13        * storage/filesystemaccess/sync-access-handle-close-worker-expected.txt: Added.
     14        * storage/filesystemaccess/sync-access-handle-close-worker.html: Added.
     15
    1162021-10-21  Ayumi Kojima  <ayumi_kojima@apple.com>
    217
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r284642 r284652  
     12021-10-21  Sihui Liu  <sihui_liu@apple.com>
     2
     3        FileSystemSyncAccessHandle should close platform file handle on close()
     4        https://bugs.webkit.org/show_bug.cgi?id=232067
     5        <rdar://problem/84517013>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt:
     10
    1112021-10-21  Rob Buis  <rbuis@igalia.com>
    212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt

    r284059 r284652  
    11
    2 FAIL SyncAccessHandle.close is idempotent promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
    3 FAIL SyncAccessHandle.close is idempotent when called immediately promise_test: Unhandled rejection with value: object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)."
    4 FAIL SyncAccessHandle.read fails after SyncAccessHandle.close settles promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
    5 FAIL SyncAccessHandle.read fails immediately after calling SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
    6 FAIL SyncAccessHandle.write fails after SyncAccessHandle.close settles promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
    7 FAIL SyncAccessHandle.write fails immediately after calling SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
    8 FAIL SyncAccessHandle.flush fails after SyncAccessHandle.close settles promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
    9 FAIL SyncAccessHandle.flush fails immediately after calling SyncAccessHandle.close promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
    10 FAIL SyncAccessHandle.getSize fails after SyncAccessHandle.close settles promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
    11 FAIL SyncAccessHandle.getSize fails immediately after calling SyncAccessHandle.close promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
    12 FAIL SyncAccessHandle.truncate fails after SyncAccessHandle.close settles promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
    13 FAIL SyncAccessHandle.truncate fails immediately after calling SyncAccessHandle.close promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
     2PASS SyncAccessHandle.close is idempotent
     3PASS SyncAccessHandle.close is idempotent when called immediately
     4PASS SyncAccessHandle.read fails after SyncAccessHandle.close settles
     5PASS SyncAccessHandle.read fails immediately after calling SyncAccessHandle.close
     6PASS SyncAccessHandle.write fails after SyncAccessHandle.close settles
     7PASS SyncAccessHandle.write fails immediately after calling SyncAccessHandle.close
     8PASS SyncAccessHandle.flush fails after SyncAccessHandle.close settles
     9PASS SyncAccessHandle.flush fails immediately after calling SyncAccessHandle.close
     10PASS SyncAccessHandle.getSize fails after SyncAccessHandle.close settles
     11PASS SyncAccessHandle.getSize fails immediately after calling SyncAccessHandle.close
     12PASS SyncAccessHandle.truncate fails after SyncAccessHandle.close settles
     13PASS SyncAccessHandle.truncate fails immediately after calling SyncAccessHandle.close
    1414
  • trunk/Source/WebCore/ChangeLog

    r284650 r284652  
     12021-10-21  Sihui Liu  <sihui_liu@apple.com>
     2
     3        FileSystemSyncAccessHandle should close platform file handle on close()
     4        https://bugs.webkit.org/show_bug.cgi?id=232067
     5        <rdar://problem/84517013>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        This patch also ensures no request is sent after close() is called.
     10
     11        Test: storage/filesystemaccess/sync-access-handle-close-worker.html
     12
     13        * Modules/filesystemaccess/FileSystemFileHandle.cpp:
     14        (WebCore::FileSystemFileHandle::createSyncAccessHandle):
     15        * Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
     16        (WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
     17        (WebCore::FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle):
     18        (WebCore::FileSystemSyncAccessHandle::isClosingOrClosed const):
     19        (WebCore::FileSystemSyncAccessHandle::truncate):
     20        (WebCore::FileSystemSyncAccessHandle::getSize):
     21        (WebCore::FileSystemSyncAccessHandle::flush):
     22        (WebCore::FileSystemSyncAccessHandle::close):
     23        (WebCore::FileSystemSyncAccessHandle::didClose):
     24        (WebCore::FileSystemSyncAccessHandle::read):
     25        (WebCore::FileSystemSyncAccessHandle::write):
     26        * Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
     27
    1282021-10-21  Dean Jackson  <dino@apple.com>
    229
  • trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp

    r284059 r284652  
    5959
    6060        auto resultValue = result.releaseReturnValue();
     61        if (resultValue.second == FileSystem::invalidPlatformFileHandle)
     62            return promise.reject(Exception { UnknownError, "Invalid platform file handle"_s });
     63
    6164        promise.settle(FileSystemSyncAccessHandle::create(protectedThis.get(), resultValue.first, resultValue.second));
    6265    });
  • trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp

    r284142 r284652  
    2828
    2929#include "BufferSource.h"
    30 #include "ExceptionOr.h"
    3130#include "FileSystemFileHandle.h"
    3231#include "JSDOMPromiseDeferred.h"
     
    4544    , m_file(file)
    4645{
     46    ASSERT(m_file != FileSystem::invalidPlatformFileHandle);
    4747}
    4848
    4949FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle()
    5050{
    51     if (!m_isClosed)
    52         m_source->close(m_identifier, [](auto) { });
     51    if (m_closeResult)
     52        return;
     53
     54    ASSERT(m_closePromises.isEmpty());
     55    m_source->close(m_identifier, [](auto) { });
     56}
     57
     58bool FileSystemSyncAccessHandle::isClosingOrClosed() const
     59{
     60    return m_closeResult || !m_closePromises.isEmpty();
    5361}
    5462
    5563void FileSystemSyncAccessHandle::truncate(unsigned long long size, DOMPromiseDeferred<void>&& promise)
    5664{
     65    if (isClosingOrClosed())
     66        return promise.reject(Exception { InvalidStateError, "AccessHandle is closing or closed"_s });
     67
    5768    m_pendingOperationCount++;
    5869    m_source->truncate(m_identifier, size, [weakThis = WeakPtr { *this }, promise = WTFMove(promise)](auto result) mutable {
     
    6677void FileSystemSyncAccessHandle::getSize(DOMPromiseDeferred<IDLUnsignedLongLong>&& promise)
    6778{
     79    if (isClosingOrClosed())
     80        return promise.reject(Exception { InvalidStateError, "AccessHandle is closing or closed"_s });
     81
    6882    m_pendingOperationCount++;
    6983    m_source->getSize(m_identifier, [weakThis = WeakPtr { *this }, promise = WTFMove(promise)](auto result) mutable {
     
    7791void FileSystemSyncAccessHandle::flush(DOMPromiseDeferred<void>&& promise)
    7892{
     93    if (isClosingOrClosed())
     94        return promise.reject(Exception { InvalidStateError, "AccessHandle is closing or closed"_s });
     95
    7996    m_pendingOperationCount++;
    8097    m_source->flush(m_identifier, [weakThis = WeakPtr { *this }, promise = WTFMove(promise)](auto result) mutable {
     
    88105void FileSystemSyncAccessHandle::close(DOMPromiseDeferred<void>&& promise)
    89106{
    90     if (m_isClosed)
    91         return promise.reject(Exception { InvalidStateError });
     107    if (m_closeResult)
     108        return promise.settle(ExceptionOr<void> { *m_closeResult });
     109   
     110    auto isClosing = !m_closePromises.isEmpty();
     111    m_closePromises.append(WTFMove(promise));
     112    if (isClosing)
     113        return;
     114
     115    FileSystem::closeFile(m_file);
     116    m_file = FileSystem::invalidPlatformFileHandle;
    92117
    93118    m_pendingOperationCount++;
    94     m_source->close(m_identifier, [weakThis = WeakPtr { *this }, promise = WTFMove(promise)](auto result) mutable {
    95         if (weakThis) {
    96             weakThis->m_pendingOperationCount--;
    97             weakThis->didClose();
    98         }
    99 
    100         promise.settle(WTFMove(result));
     119    m_source->close(m_identifier, [this, protectedThis = Ref { *this }](auto result) mutable {
     120        m_pendingOperationCount--;
     121        didClose(WTFMove(result));
    101122    });
    102123}
    103124
    104 void FileSystemSyncAccessHandle::didClose()
     125void FileSystemSyncAccessHandle::didClose(ExceptionOr<void>&& result)
    105126{
    106     m_isClosed = true;
     127    m_closeResult = WTFMove(result);
     128
     129    auto promises = std::exchange(m_closePromises, { });
     130    for (auto promise : promises)
     131        promise.settle(ExceptionOr<void> { *m_closeResult });
    107132}
    108133
     
    111136    ASSERT(!isMainThread());
    112137
    113     if (m_file == FileSystem::invalidPlatformFileHandle || m_isClosed)
    114         return Exception { InvalidStateError };
     138    if (isClosingOrClosed())
     139        return Exception { InvalidStateError, "AccessHandle is closing or closed"_s };
    115140
    116141    if (m_pendingOperationCount)
     
    132157    ASSERT(!isMainThread());
    133158
    134     if (m_file == FileSystem::invalidPlatformFileHandle || m_isClosed)
    135         return Exception { InvalidStateError };
     159    if (isClosingOrClosed())
     160        return Exception { InvalidStateError, "AccessHandle is closing or closed"_s };
    136161
    137162    if (m_pendingOperationCount)
  • trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h

    r284059 r284652  
    2727
    2828#include "BufferSource.h"
     29#include "ExceptionOr.h"
    2930#include "FileSystemSyncAccessHandleIdentifier.h"
    3031#include "IDLTypes.h"
     
    3637class FileSystemFileHandle;
    3738template<typename> class DOMPromiseDeferred;
    38 template<typename> class ExceptionOr;
    3939
    4040class FileSystemSyncAccessHandle : public RefCounted<FileSystemSyncAccessHandle>, public CanMakeWeakPtr<FileSystemSyncAccessHandle> {
     
    5151    void flush(DOMPromiseDeferred<void>&&);
    5252    void close(DOMPromiseDeferred<void>&&);
    53     void didClose();
     53    void didClose(ExceptionOr<void>&&);
    5454    ExceptionOr<unsigned long long> read(BufferSource&&, FilesystemReadWriteOptions);
    5555    ExceptionOr<unsigned long long> write(BufferSource&&, FilesystemReadWriteOptions);
     
    5757private:
    5858    FileSystemSyncAccessHandle(FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle);
     59    bool isClosingOrClosed() const;
    5960
    6061    Ref<FileSystemFileHandle> m_source;
    6162    FileSystemSyncAccessHandleIdentifier m_identifier;
    62     bool m_isClosed { false };
    6363    uint64_t m_pendingOperationCount { 0 };
    6464    FileSystem::PlatformFileHandle m_file;
     65    std::optional<ExceptionOr<void>> m_closeResult;
     66    Vector<DOMPromiseDeferred<void>> m_closePromises;
    6567};
    6668
Note: See TracChangeset for help on using the changeset viewer.