WebAssembly / wasi-threads

145 stars 8 forks source link

Use WIT's result<> type for `thread-spawn`'s return values #29

Open loganek opened 1 year ago

loganek commented 1 year ago

Because thread-spawn can fail, we use return value to communicate error code. We also use return value to communicate success and pass thread id to the user. This usecase nicely fits into variant type, and more specifically - result<>. It also feels like an idiomatic way of handling this kind of usecase in WIT.

I propose we update the type of thread-spawn to be:

type thread-id = u32

start-arg

result<thread-id, errno>

where thread-id is a non-negative integer (type start-arg = u32) and errno is an enum representing all potential errors returned by thread-spawn.

Please note that the consequence of this change is updated C interface:

void __wasi_thread_spawn(int32_t, int32_t);

where the second parameter is a pointer to a memory dedicated for the return value.

I'm seeking for feedback/suggestions; once we have a high-level agreement, the next steps are: [ ] define (initial) set of error codes [ ] update proposal and WIT definition (https://github.com/WebAssembly/wasi-threads/pull/28) [ ] update toolchains (wasi-libc, ...?) [ ] update runtimes that already implemented the proposal or have the work in-progress (wasmtime, WAMR, ...?)

See also: https://github.com/WebAssembly/wasi-threads/pull/26

yamt commented 1 year ago
abrown commented 1 year ago

CC-ing @lukewagner who may have an opinion about this issue. If wasi-threads is defined as a core module, should it use WIT's result type? Related: do you foresee that WIT gain the ability to define core modules?

lukewagner commented 1 year ago

When WIT is extended to describe core modules, I would expect, as a starting point, it would start with just core value types. While you could imagine supporting a subset of component-level types that had a clear mapping to scalar core value types, it would pretty quickly stop working as soon as linear memory got involved and I expect what we'd want would look a lot more like the explicit "pointer" approach of witx (from which you could generate C header-file-style bindings, but not higher-level language bindings automatically). Without thinking through the design of this, it's hard to know if we'd want to attempt to share types like result between the component-level and core-level bindings or whether we'd simply want a clean split between the two sets of types; I could imagine it going either way and it's hard to know which w/o thinking through the details.