Skip to content

Commit 35d8089

Browse files
committed
c-api: support yielding in epoch deadline callback
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
1 parent f3dbed5 commit 35d8089

2 files changed

Lines changed: 45 additions & 7 deletions

File tree

crates/c-api/include/wasmtime/store.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,44 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_context_set_wasi(wasmtime_context_t *
200200
*/
201201
WASM_API_EXTERN void wasmtime_context_set_epoch_deadline(wasmtime_context_t *context, uint64_t ticks_beyond_current);
202202

203+
// \brief An enum for the behavior before extending the epoch deadline.
204+
typedef wasmtime_update_deadline_kind_t uint8_t;
205+
// \brief Directly continue to updating the deadline and executing WebAssembly.
206+
#define WASMTIME_UPDATE_DEADLINE_CONTINUE 0
207+
// \brief Yield control (via async support) then update the deadline.
208+
#define WASMTIME_UPDATE_DEADLINE_YIELD 1
209+
203210
/**
204211
* \brief Configures epoch deadline callback to C function.
205212
*
206213
* This function configures a store-local callback function that will be
207214
* called when the running WebAssembly function has exceeded its epoch
208-
* deadline. That function can return a #wasmtime_error_t to terminate
209-
* the function, or set the delta argument and return NULL to update the
210-
* epoch deadline and resume function execution.
215+
* deadline. That function can:
216+
* - return a #wasmtime_error_t to terminate the function
217+
* - set the delta argument and return NULL to update the
218+
* epoch deadline delta and resume function execution.
219+
* - set the delta argument, update the epoch deadline,
220+
* set update_kind to WASMTIME_UPDATE_DEADLINE_YIELD,
221+
* and return NULL to yield (via async support) and
222+
* resume function execution.
223+
*
224+
* To use WASMTIME_UPDATE_DEADLINE_YIELD async support must be enabled
225+
* for this store.
211226
*
212227
* See also #wasmtime_config_epoch_interruption_set and
213228
* #wasmtime_context_set_epoch_deadline.
214229
*/
215-
WASM_API_EXTERN void wasmtime_store_epoch_deadline_callback(wasmtime_store_t *store, wasmtime_error_t* (*func)(wasmtime_context_t*, void*, uint64_t*), void *data);
230+
WASM_API_EXTERN void wasmtime_store_epoch_deadline_callback(
231+
wasmtime_store_t *store,
232+
wasmtime_error_t* (*func)(
233+
wasmtime_context_t* context,
234+
void* data,
235+
uint64_t* epoch_deadline_delta,
236+
wasmtime_update_deadline_kind_t* update_kind
237+
),
238+
void *data,
239+
void (*finalizer)(void*)
240+
);
216241

217242
#ifdef __cplusplus
218243
} // extern "C"

crates/c-api/src/store.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,29 +121,42 @@ impl CallbackDataPtr {
121121
unsafe impl Send for CallbackDataPtr {}
122122
unsafe impl Sync for CallbackDataPtr {}
123123

124+
pub type wasmtime_update_deadline_kind_t = u8;
125+
pub const WASMTIME_UPDATE_DEADLINE_CONTINUE: wasmtime_update_deadline_kind_t = 0;
126+
pub const WASMTIME_UPDATE_DEADLINE_YIELD: wasmtime_update_deadline_kind_t = 1;
127+
124128
#[no_mangle]
125129
pub extern "C" fn wasmtime_store_epoch_deadline_callback(
126130
store: &mut wasmtime_store_t,
127131
func: extern "C" fn(
128132
CStoreContextMut<'_>,
129133
*mut c_void,
130134
*mut u64,
135+
*mut wasmtime_update_deadline_kind_t,
131136
) -> Option<Box<wasmtime_error_t>>,
132137
data: *mut c_void,
138+
finalizer: Option<extern "C" fn(*mut c_void)>,
133139
) {
134-
let sendable = CallbackDataPtr { ptr: data };
140+
let foreign = crate::ForeignData { data, finalizer };
135141
store.store.epoch_deadline_callback(move |mut store_ctx| {
142+
let _ = &foreign; // Move foreign into this closure
136143
let mut delta: u64 = 0;
144+
let mut kind = WASMTIME_UPDATE_DEADLINE_CONTINUE;
137145
let result = (func)(
138146
store_ctx.as_context_mut(),
139-
sendable.as_mut_ptr(),
147+
foreign.data,
140148
&mut delta as *mut u64,
149+
&mut kind as *mut wasmtime_update_deadline_kind_t,
141150
);
142151
match result {
143152
Some(err) => Err(wasmtime::Error::from(<wasmtime_error_t as Into<
144153
anyhow::Error,
145154
>>::into(*err))),
146-
None => Ok(UpdateDeadline::Continue(delta)),
155+
None if kind == WASMTIME_UPDATE_DEADLINE_CONTINUE => {
156+
Ok(UpdateDeadline::Continue(delta))
157+
}
158+
None if kind == WASMTIME_UPDATE_DEADLINE_YIELD => Ok(UpdateDeadline::Yield(delta)),
159+
_ => panic!("unknown wasmtime_update_deadline_kind_t: {}", kind),
147160
}
148161
});
149162
}

0 commit comments

Comments
 (0)