Skip to content

Commit c121f74

Browse files
authored
[WasmFS] Allow backends to report errors from flush (#17781)
And catch and report such errors in the OPFS backend to prevent errors from causing the async task to hang and create deadlocks.
1 parent dec3398 commit c121f74

File tree

12 files changed

+31
-22
lines changed

12 files changed

+31
-22
lines changed

src/library_wasmfs_opfs.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,14 @@ mergeInto(LibraryManager.library, {
402402
},
403403

404404
_wasmfs_opfs_flush_access__deps: ['$wasmfsOPFSAccessHandles'],
405-
_wasmfs_opfs_flush_access: async function(ctx, accessID) {
405+
_wasmfs_opfs_flush_access: async function(ctx, accessID, errPtr) {
406406
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
407-
// TODO: Error handling
408-
await accessHandle.flush();
407+
try {
408+
await accessHandle.flush();
409+
} catch {
410+
let err = -{{{ cDefine('EIO') }}};
411+
{{{ makeSetValue('errPtr', 0, 'err', 'i32') }}};
412+
}
409413
_emscripten_proxy_finish(ctx);
410414
}
411415
});

system/lib/wasmfs/backends/node_backend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class NodeFile : public DataFile {
179179
return nwritten;
180180
}
181181

182-
void flush() override {
182+
int flush() override {
183183
WASMFS_UNREACHABLE("TODO: implement NodeFile::flush");
184184
}
185185
};

system/lib/wasmfs/backends/opfs_backend.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ void _wasmfs_opfs_set_size_file(em_proxying_ctx* ctx,
107107
uint32_t size,
108108
int* err);
109109

110-
void _wasmfs_opfs_flush_access(em_proxying_ctx* ctx, int access_id);
110+
void _wasmfs_opfs_flush_access(em_proxying_ctx* ctx, int access_id, int* err);
111111

112112
} // extern "C"
113113

@@ -313,18 +313,20 @@ class OPFSFile : public DataFile {
313313
return nwritten;
314314
}
315315

316-
void flush() override {
316+
int flush() override {
317+
int err = 0;
317318
switch (state.getKind()) {
318319
case OpenState::Access:
319320
proxy([&](auto ctx) {
320-
_wasmfs_opfs_flush_access(ctx.ctx, state.getAccessID());
321+
_wasmfs_opfs_flush_access(ctx.ctx, state.getAccessID(), &err);
321322
});
322323
break;
323324
case OpenState::Blob:
324325
case OpenState::None:
325326
default:
326327
break;
327328
}
329+
return err;
328330
}
329331
};
330332

system/lib/wasmfs/backends/proxied_file_backend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class ProxiedFile : public DataFile {
4747
return result;
4848
}
4949

50-
void flush() override {}
50+
int flush() override { return 0; }
5151

5252
// Querying the size of the Proxied File returns the size of the underlying
5353
// file given by the proxying mechanism.

system/lib/wasmfs/file.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ class DataFile : public File {
146146
// opened. Returns 0 on success or a negative error code.
147147
virtual int setSize(size_t size) = 0;
148148

149-
// TODO: Design a proper API for flushing files.
150-
virtual void flush() = 0;
149+
// Sync the file data to the underlying persistent storage, if any. Returns 0
150+
// on success or a negative error code.
151+
virtual int flush() = 0;
151152

152153
public:
153154
static constexpr FileKind expectedKind = File::DataFileKind;
@@ -327,7 +328,7 @@ class DataFile::Handle : public File::Handle {
327328
[[nodiscard]] int setSize(size_t size) { return getFile()->setSize(size); }
328329

329330
// TODO: Design a proper API for flushing files.
330-
void flush() { getFile()->flush(); }
331+
[[nodiscard]] int flush() { return getFile()->flush(); }
331332

332333
// This function loads preloaded files from JS Memory into this DataFile.
333334
// TODO: Make this virtual so specific backends can specialize it for better

system/lib/wasmfs/js_impl_backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class JSImplFile : public DataFile {
9494
getBackendIndex(), getFileIndex(), buf, len, offset);
9595
}
9696

97-
void flush() override {}
97+
int flush() override { return 0; }
9898

9999
size_t getSize() override {
100100
return _wasmfs_jsimpl_get_size(getBackendIndex(), getFileIndex());

system/lib/wasmfs/memory_backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MemoryFile : public DataFile {
2323
int close() override { return 0; }
2424
ssize_t write(const uint8_t* buf, size_t len, off_t offset) override;
2525
ssize_t read(uint8_t* buf, size_t len, off_t offset) override;
26-
void flush() override {}
26+
int flush() override { return 0; }
2727
size_t getSize() override { return buffer.size(); }
2828
int setSize(size_t size) override {
2929
buffer.resize(size);

system/lib/wasmfs/pipe_backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class PipeFile : public DataFile {
4444
return len;
4545
}
4646

47-
void flush() override {}
47+
int flush() override { return 0; }
4848

4949
size_t getSize() override { return data->size(); }
5050

system/lib/wasmfs/proxied_async_js_impl_backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class ProxiedAsyncJSImplFile : public DataFile {
106106
return result;
107107
}
108108

109-
void flush() override {}
109+
int flush() override { return 0; }
110110

111111
size_t getSize() override {
112112
size_t result;

system/lib/wasmfs/special_files.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class NullFile : public DataFile {
2828

2929
ssize_t read(uint8_t* buf, size_t len, off_t offset) override { return 0; }
3030

31-
void flush() override {}
31+
int flush() override { return 0; }
3232
size_t getSize() override { return 0; }
3333
int setSize(size_t size) override { return -EPERM; }
3434

@@ -49,7 +49,7 @@ class StdinFile : public DataFile {
4949
abort();
5050
};
5151

52-
void flush() override {}
52+
int flush() override { return 0; }
5353
size_t getSize() override { return 0; }
5454
int setSize(size_t size) override { return -EPERM; }
5555

@@ -69,12 +69,13 @@ class WritingStdFile : public DataFile {
6969
return -__WASI_ERRNO_INVAL;
7070
};
7171

72-
void flush() override {
72+
int flush() override {
7373
// Write a null to flush the output if we have content.
7474
if (!writeBuffer.empty()) {
7575
const uint8_t nothing = '\0';
7676
write(&nothing, 1, 0);
7777
}
78+
return 0;
7879
}
7980

8081
size_t getSize() override { return 0; }
@@ -150,7 +151,7 @@ class RandomFile : public DataFile {
150151
return len;
151152
};
152153

153-
void flush() override {}
154+
int flush() override { return 0; }
154155
size_t getSize() override { return 0; }
155156
int setSize(size_t size) override { return -EPERM; }
156157

0 commit comments

Comments
 (0)