-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Support OPFS on the main thread with JSPI. #19063
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The OPFS backend will now use async reaad/writes when used on the main thread. The ProxyWorker is stubbed out and calls are directly dispatched into JS. The JS side uses a new FileSystemASyncAccessHandle class that matches the sync version of the class, but has async read/writes. Hopefully, we can one day replace that with something from the platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM % small comments.
What happens if you don't enable threads and also don't enable JSPI? Does it blow up or give a nice error message or somewhere in between?
src/library_wasmfs_opfs.js
Outdated
'$wasmfsOPFSAccessHandles'], | ||
'$wasmfsOPFSAccessHandles', '$wasmfsOPFSProxyFinish', | ||
#if !USE_PTHREADS | ||
'$wasmfsOPFSCreateASyncAccessHandle' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'$wasmfsOPFSCreateASyncAccessHandle' | |
'$wasmfsOPFSCreateAsyncAccessHandle' |
src/library_wasmfs_opfs.js
Outdated
// TODO: Remove this once the Access Handles API has settled. | ||
if (FileSystemFileHandle.prototype.createSyncAccessHandle.length == 0) { | ||
accessHandle = await fileHandle.createSyncAccessHandle(); | ||
} else { | ||
accessHandle = await fileHandle.createSyncAccessHandle( | ||
{mode: "in-place"}); | ||
} | ||
#else | ||
accessHandle = await wasmfsOPFSCreateASyncAccessHandle(fileHandle); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
accessHandle = await wasmfsOPFSCreateASyncAccessHandle(fileHandle); | |
accessHandle = await wasmfsOPFSCreateAsyncAccessHandle(fileHandle); |
src/library_wasmfs_opfs.js
Outdated
}, | ||
|
||
$wasmfsOPFSCreateASyncAccessHandle__deps: ['$FileSystemAsyncAccessHandle'], | ||
$wasmfsOPFSCreateASyncAccessHandle: function(fileHandle) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$wasmfsOPFSCreateASyncAccessHandle: function(fileHandle) { | |
$wasmfsOPFSCreateAsyncAccessHandle: function(fileHandle) { |
// can be directly executed since they are all async. | ||
template <typename T> | ||
void operator()(T func) { | ||
if constexpr (std::is_invocable<T&, ProxyingQueue::ProxyingCtx>::value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very slightly simpler:
if constexpr (std::is_invocable<T&, ProxyingQueue::ProxyingCtx>::value) { | |
if constexpr (std::is_invocable_v<T&, ProxyingQueue::ProxyingCtx>) { |
In debug builds the same assert as before will trigger: |
Makes sense. I guess if we add a new constructor that returns a promise (and is therefore usable on the main thread even without JSPI), we have to have a similar assertion to avoid trying to execute any async file operations when neither JSPI nor threads are enabled? |
The OPFS backend will now use async reaad/writes when used on the main thread. The ProxyWorker is stubbed out and calls are directly dispatched into JS. The JS side uses a new FileSystemASyncAccessHandle class that matches the sync version of the class, but has async read/writes. Hopefully, we can one day replace that with something from the platform.