Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make all FileSystemSyncAccessHandle methods sync
https://bugs.webkit.org/show_bug.cgi?id=247071
rdar://problem/101620396

Reviewed by Youenn Fablet.

To match latest spec: https://fs.spec.whatwg.org/#api-filesystemsyncaccesshandle. Chrome has already shipped it.

* LayoutTests/imported/w3c/web-platform-tests/fs/FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fs/FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fs/FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fs/FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fs/idlharness.https.any.worker-expected.txt:
* LayoutTests/storage/filesystemaccess/resources/sync-access-handle-basics.js:
* LayoutTests/storage/filesystemaccess/resources/sync-access-handle-close.js:
(testFunction):
(testFunctions):
(async testMultipleHandles):
(async test):
(testSyncFunction): Deleted.
(async testAsyncFunction): Deleted.
(async testFunctions): Deleted.
* LayoutTests/storage/filesystemaccess/resources/sync-access-handle-read-write.js:
(async test):
* LayoutTests/storage/filesystemaccess/sync-access-handle-close-worker-expected.txt:
* LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt:
* Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp:
(WebCore::FileSystemFileHandle::createSyncAccessHandle):
(WebCore::FileSystemFileHandle::closeSyncAccessHandle):
* Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h:
* Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h:
* Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
(WebCore::FileSystemSyncAccessHandle::~FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::truncate):
(WebCore::FileSystemSyncAccessHandle::getSize):
(WebCore::FileSystemSyncAccessHandle::flush):
(WebCore::FileSystemSyncAccessHandle::close):
(WebCore::FileSystemSyncAccessHandle::closeInternal):
(WebCore::FileSystemSyncAccessHandle::read):
(WebCore::FileSystemSyncAccessHandle::write):
(WebCore::FileSystemSyncAccessHandle::stop):
(WebCore::FileSystemSyncAccessHandle::invalidate):
(WebCore::FileSystemSyncAccessHandle::isClosingOrClosed const): Deleted.
(WebCore::FileSystemSyncAccessHandle::closeFile): Deleted.
(WebCore::FileSystemSyncAccessHandle::didCloseFile): Deleted.
(WebCore::FileSystemSyncAccessHandle::closeBackend): Deleted.
(WebCore::FileSystemSyncAccessHandle::didCloseBackend): Deleted.
(WebCore::FileSystemSyncAccessHandle::completePromise): Deleted.
* Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
* Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl:
* Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp:
(WebCore::WorkerFileSystemStorageConnection::closeSyncAccessHandle):
* Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h:
* Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp:
(WebKit::NetworkStorageManager::closeSyncAccessHandle):
* Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h:
* Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in:
* Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp:
(WebKit::WebFileSystemStorageConnection::closeSyncAccessHandle):
* Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.h:

Canonical link: https://commits.webkit.org/258473@main
  • Loading branch information
szewai committed Jan 5, 2023
1 parent 025094e commit acd30cd
Show file tree
Hide file tree
Showing 23 changed files with 114 additions and 299 deletions.
@@ -1,8 +1,8 @@

FAIL SyncAccessHandle.close is idempotent assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.read fails after SyncAccessHandle.close assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.write fails after SyncAccessHandle.close assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.flush fails after SyncAccessHandle.close assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.getSize fails after SyncAccessHandle.close assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.truncate fails after SyncAccessHandle.handle.close assert_equals: expected (undefined) undefined but got (object) object "[object Promise]"
FAIL SyncAccessHandle.close is idempotent promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"
FAIL SyncAccessHandle.read fails after SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"
FAIL SyncAccessHandle.write fails after SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"
FAIL SyncAccessHandle.flush fails after SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"
FAIL SyncAccessHandle.getSize fails after SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"
FAIL SyncAccessHandle.truncate fails after SyncAccessHandle.handle.close promise_test: Unhandled rejection with value: object "InvalidStateError: AccessHandle is closed"

@@ -1,4 +1,4 @@

PASS Test flush on an empty file.
FAIL SyncAccessHandle.read returns bytes written by SyncAccessHandle.write after SyncAccessHandle.flush promise_test: Unhandled rejection with value: object "InvalidStateError: Access handle has unfinished operation"
PASS SyncAccessHandle.read returns bytes written by SyncAccessHandle.write after SyncAccessHandle.flush

@@ -1,3 +1,3 @@

FAIL test SyncAccessHandle.getSize after SyncAccessHandle.write assert_equals: expected (number) 0 but got (object) object "[object Promise]"
PASS test SyncAccessHandle.getSize after SyncAccessHandle.write

@@ -1,4 +1,4 @@

FAIL test SyncAccessHandle.truncate with different sizes assert_equals: expected (number) 4 but got (object) object "[object Promise]"
FAIL test SyncAccessHandle.truncate after SyncAccessHandle.write promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
PASS test SyncAccessHandle.truncate with different sizes
PASS test SyncAccessHandle.truncate after SyncAccessHandle.write

Expand Up @@ -49,17 +49,9 @@ PASS FileSystemSyncAccessHandle interface: existence and properties of interface
PASS FileSystemSyncAccessHandle interface: existence and properties of interface prototype object's @@unscopables property
PASS FileSystemSyncAccessHandle interface: operation read(BufferSource, optional FileSystemReadWriteOptions)
PASS FileSystemSyncAccessHandle interface: operation write(BufferSource, optional FileSystemReadWriteOptions)
FAIL FileSystemSyncAccessHandle interface: operation truncate(unsigned long long) assert_throws_js: calling operation with this = null didn't throw TypeError function "function () {
fn.apply(obj, args);
}" did not throw
FAIL FileSystemSyncAccessHandle interface: operation getSize() assert_throws_js: calling operation with this = null didn't throw TypeError function "function () {
fn.apply(obj, args);
}" did not throw
FAIL FileSystemSyncAccessHandle interface: operation flush() assert_throws_js: calling operation with this = null didn't throw TypeError function "function () {
fn.apply(obj, args);
}" did not throw
FAIL FileSystemSyncAccessHandle interface: operation close() assert_throws_js: calling operation with this = null didn't throw TypeError function "function () {
fn.apply(obj, args);
}" did not throw
PASS FileSystemSyncAccessHandle interface: operation truncate(unsigned long long)
PASS FileSystemSyncAccessHandle interface: operation getSize()
PASS FileSystemSyncAccessHandle interface: operation flush()
PASS FileSystemSyncAccessHandle interface: operation close()
PASS StorageManager interface: operation getDirectory()

Expand Up @@ -46,13 +46,13 @@ function createSyncAccessHandle(fromHandle)

function getSize(accessHandle)
{
accessHandle.getSize().then((result) => {
size = result;
try {
size = accessHandle.getSize();
shouldBe("size", "0");
createSecondSyncAcessHandle(fileHandle);
}).catch((error) => {
} catch(error) {
finishTest(error);
});
}
}

function createSecondSyncAcessHandle(fromHandle)
Expand All @@ -73,12 +73,13 @@ function createSecondSyncAcessHandle(fromHandle)

function close()
{
accessHandle1.close().then((result) => {
try {
accessHandle1.close();
debug("accessHandle1 is closed");
createSecondSyncAcessHandle(fileHandle);
}).catch((error) => {
} catch(error) {
finishTest(error);
});
}
}

getDirectory();
Expand Up @@ -11,42 +11,26 @@ const options = { "at" : 0 };
var functions = [
{ name : "getSize" },
{ name : "flush" },
{ name : "read", args : [buffer, options], sync : true },
{ name : "write", args : [buffer, options], sync : true },
{ name : "read", args : [buffer, options] },
{ name : "write", args : [buffer, options] },
];

function testSyncFunction(currentFunction)
function testFunction(targetFunction)
{
try {
var result = accessHandle[currentFunction.name].apply(accessHandle, currentFunction.args);
var result = accessHandle[targetFunction.name].apply(accessHandle, targetFunction.args);
return null;
} catch (err) {
return err;
} catch (error) {
return error;
}
}

async function testAsyncFunction(func)
{
var promise = accessHandle[func.name].apply(accessHandle, func.args);
return promise.then((value) => {
return func.name + " function should throw exception but didn't";
}, (err) => {
return err;
});
}

async function testFunctions()
function testFunctions()
{
for (const func of functions) {
debug("testing " + func.name);

if (func.sync) {
error = testSyncFunction(func);
} else {
error = await testAsyncFunction(func);
}

shouldBeEqualToString("error.toString()", "InvalidStateError: AccessHandle is closing or closed");
error = testFunction(func);
shouldBeEqualToString("error.toString()", "InvalidStateError: AccessHandle is closed");
}
}

Expand All @@ -56,7 +40,7 @@ async function testMultipleHandles()
for (let i = 0; i < 512; i++) {
try {
accessHandle = await fileHandle.createSyncAccessHandle();
await accessHandle.close();
accessHandle.close();
} catch (err) {
throw "Failed at No." + i + " handle: " + err.toString();
}
Expand All @@ -73,13 +57,9 @@ async function test()
fileHandle = await rootHandle.getFileHandle("sync-access-handle-close.txt", { "create" : true });
accessHandle = await fileHandle.createSyncAccessHandle();

var closePromise = accessHandle.close();
debug("test after invoking close():");
await testFunctions();

debug("test after close() is done:");
await closePromise;
await testFunctions();
debug("test closing handle:");
accessHandle.close();
testFunctions();

debug("test closing multiple handles:");
await testMultipleHandles();
Expand Down
Expand Up @@ -55,7 +55,7 @@ async function test()
await rootHandle.removeEntry("sync-access-handle.txt").then(() => { }, () => { });
var fileHandle = await rootHandle.getFileHandle("sync-access-handle.txt", { "create" : true });
accessHandle = await fileHandle.createSyncAccessHandle();
fileSize = await accessHandle.getSize();
fileSize = accessHandle.getSize();
shouldBe("fileSize", "0");

debug("test read() and write():");
Expand All @@ -75,22 +75,22 @@ async function test()
shouldThrow("accessHandle.write(new ArrayBuffer(1), { \"at\" : Number.MAX_SAFE_INTEGER })");

debug("test flush():");
await accessHandle.flush();
fileSize = await accessHandle.getSize();
accessHandle.flush();
fileSize = accessHandle.getSize();
shouldBe("fileSize", "totalWriteSize");

debug("test truncate():");
await accessHandle.truncate(4);
await accessHandle.flush();
fileSize = await accessHandle.getSize();
accessHandle.truncate(4);
accessHandle.flush();
fileSize = accessHandle.getSize();
shouldBe("fileSize", "4");

debug("test write() with pending operation:");
evalAndLog("accessHandle.truncate(0)");
readBuffer = new ArrayBuffer(4);
shouldThrow("accessHandle.read(readBuffer, { \"at\" : 0 })");
shouldBe("accessHandle.read(readBuffer, { \"at\" : 0 })", "0");

await accessHandle.close();
accessHandle.close();
finishTest();
} catch (error) {
finishTest(error);
Expand Down
Expand Up @@ -4,24 +4,15 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE


Starting worker: resources/sync-access-handle-close.js
[Worker] test after invoking close():
[Worker] test closing handle:
[Worker] testing getSize
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closed"
[Worker] testing flush
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closed"
[Worker] testing read
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closed"
[Worker] testing write
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
[Worker] test after close() is done:
[Worker] testing getSize
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
[Worker] testing flush
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
[Worker] testing read
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
[Worker] testing write
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closing or closed"
PASS [Worker] error.toString() is "InvalidStateError: AccessHandle is closed"
[Worker] test closing multiple handles:
[Worker] Create and close access handles successfully
PASS successfullyParsed is true
Expand Down
Expand Up @@ -27,7 +27,7 @@ PASS [Worker] fileSize is totalWriteSize
PASS [Worker] fileSize is 4
[Worker] test write() with pending operation:
[Worker] accessHandle.truncate(0)
PASS [Worker] accessHandle.read(readBuffer, { "at" : 0 }) threw exception InvalidStateError: Access handle has unfinished operation.
PASS [Worker] accessHandle.read(readBuffer, { "at" : 0 }) is 0
PASS successfullyParsed is true

TEST COMPLETE
Expand Down
Expand Up @@ -84,20 +84,20 @@ void FileSystemFileHandle::createSyncAccessHandle(DOMPromiseDeferred<IDLInterfac

auto* context = protectedThis->scriptExecutionContext();
if (!context) {
protectedThis->closeSyncAccessHandle(identifier, { });
protectedThis->closeSyncAccessHandle(identifier);
return promise.reject(Exception { InvalidStateError, "Context has stopped"_s });
}

promise.resolve(FileSystemSyncAccessHandle::create(*context, protectedThis.get(), identifier, WTFMove(file)));
});
}

void FileSystemFileHandle::closeSyncAccessHandle(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&& completionHandler)
void FileSystemFileHandle::closeSyncAccessHandle(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier)
{
if (isClosed())
return completionHandler(Exception { InvalidStateError, "Handle is closed"_s });
return;

connection().closeSyncAccessHandle(identifier(), accessHandleIdentifier, WTFMove(completionHandler));
connection().closeSyncAccessHandle(identifier(), accessHandleIdentifier);
}

void FileSystemFileHandle::registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier identifier, FileSystemSyncAccessHandle& handle)
Expand Down
Expand Up @@ -41,7 +41,7 @@ class FileSystemFileHandle final : public FileSystemHandle {
void getFile(DOMPromiseDeferred<IDLInterface<File>>&&);

void createSyncAccessHandle(DOMPromiseDeferred<IDLInterface<FileSystemSyncAccessHandle>>&&);
void closeSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&&);
void closeSyncAccessHandle(FileSystemSyncAccessHandleIdentifier);
void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, FileSystemSyncAccessHandle&);
void unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier);

Expand Down
Expand Up @@ -64,7 +64,7 @@ class FileSystemStorageConnection : public ThreadSafeRefCounted<FileSystemStorag
virtual void resolve(FileSystemHandleIdentifier, FileSystemHandleIdentifier, ResolveCallback&&) = 0;
virtual void getFile(FileSystemHandleIdentifier, StringCallback&&) = 0;
virtual void createSyncAccessHandle(FileSystemHandleIdentifier, GetAccessHandleCallback&&) = 0;
virtual void closeSyncAccessHandle(FileSystemHandleIdentifier, FileSystemSyncAccessHandleIdentifier, VoidCallback&&) = 0;
virtual void closeSyncAccessHandle(FileSystemHandleIdentifier, FileSystemSyncAccessHandleIdentifier) = 0;
virtual void registerSyncAccessHandle(FileSystemSyncAccessHandleIdentifier, ScriptExecutionContextIdentifier) = 0;
virtual void unregisterSyncAccessHandle(FileSystemSyncAccessHandleIdentifier) = 0;
virtual void invalidateAccessHandle(WebCore::FileSystemSyncAccessHandleIdentifier) = 0;
Expand Down

0 comments on commit acd30cd

Please sign in to comment.