Skip to content
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

[Fix] impl Drop for FiberFuture #59

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions crates/wasmedge-sys/src/async/fiber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ impl<'a> FiberFuture<'a> {

Ok(slot.unwrap())
}

fn resume(&mut self, val: Result<(), ()>) -> Result<Result<(), ()>, ()> {
let async_cx = AsyncCx {
current_suspend: self.current_suspend,
current_poll_cx: self.current_poll_cx,
};
ASYNC_CX.set(&async_cx, || self.fiber.resume(val))
}
}
impl<'a> Future for FiberFuture<'a> {
type Output = Result<(), ()>;
Expand All @@ -79,6 +87,19 @@ impl<'a> Future for FiberFuture<'a> {
}
unsafe impl Send for FiberFuture<'_> {}

impl Drop for FiberFuture<'_> {
fn drop(&mut self) {
if !self.fiber.done() {
let result = self.resume(Err(()));
// This resumption with an error should always complete the
// fiber. While it's technically possible for host code to catch
// the trap and re-resume, we'd ideally like to signal that to
// callers that they shouldn't be doing that.
debug_assert!(result.is_ok());
}
}
}

type FiberSuspend = Suspend<Result<(), ()>, (), Result<(), ()>>;

scoped_tls::scoped_thread_local!(static ASYNC_CX: AsyncCx);
Expand Down
2 changes: 1 addition & 1 deletion crates/wasmedge-sys/src/async/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ extern "C" fn wrap_async_wasi_fn<T: 'static>(
let result = match unsafe { async_cx.block_on(future.as_mut()) } {
Ok(Ok(ret)) => Ok(ret),
Ok(Err(err)) => Err(err),
Err(_err) => Err(HostFuncError::User(0x87)),
Err(_err) => Err(HostFuncError::Runtime(0x07)),
};

// parse result
Expand Down
15 changes: 12 additions & 3 deletions crates/wasmedge-sys/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,12 @@ mod tests {
let result = FuncType::create([ValType::ExternRef, ValType::I32], [ValType::I32]);
assert!(result.is_ok());
let func_ty = result.unwrap();
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();
// add the function into the import_obj module
Expand Down Expand Up @@ -714,8 +719,12 @@ mod tests {
assert!(result.is_ok());

let ty = FuncType::create([], [])?;
let async_hello_func =
Function::create_async_func::<NeverType>(&ty, Box::new(async_hello), None, 0)?;
let async_hello_func = Function::create_async_func::<NeverType>(
&ty,
Box::new(async_hello),
std::ptr::null_mut(),
0,
)?;
let mut import = ImportModule::<NeverType>::create("extern", None)?;
import.add_func("async_hello", async_hello_func);

Expand Down
79 changes: 48 additions & 31 deletions crates/wasmedge-sys/src/instance/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ extern "C" fn wrap_async_fn(
let result = match unsafe { async_cx.block_on(future.as_mut()) } {
Ok(Ok(ret)) => Ok(ret),
Ok(Err(err)) => Err(err),
Err(_err) => Err(HostFuncError::User(0x87)),
Err(_err) => Err(HostFuncError::Runtime(0x07)),
};

// parse result
Expand Down Expand Up @@ -228,15 +228,10 @@ impl Function {
pub fn create_sync_func<T>(
ty: &FuncType,
real_fn: BoxedFn,
data: Option<Box<T>>,
data: *mut T,
cost: u64,
) -> WasmEdgeResult<Self> {
let data = match data {
Some(d) => Box::into_raw(d) as *mut std::ffi::c_void,
None => std::ptr::null_mut(),
};

unsafe { Self::create_with_data(ty, real_fn, data, cost) }
unsafe { Self::create_with_data(ty, real_fn, data as _, cost) }
}

/// Creates a [host function](crate::Function) with the given function type.
Expand Down Expand Up @@ -317,14 +312,9 @@ impl Function {
pub fn create_async_func<T: Send + Sync>(
ty: &FuncType,
real_fn: BoxedAsyncFn,
data: Option<Box<T>>,
data: *mut T,
cost: u64,
) -> WasmEdgeResult<Self> {
let data = match data {
Some(d) => Box::into_raw(d) as *mut std::ffi::c_void,
None => std::ptr::null_mut(),
};

let mut map_host_func = ASYNC_HOST_FUNCS.write();

// generate key for the coming host function
Expand All @@ -341,7 +331,7 @@ impl Function {
ty.inner.0,
Some(wrap_async_fn),
key as *const usize as *mut c_void,
data,
data as _,
cost,
)
};
Expand Down Expand Up @@ -814,7 +804,7 @@ mod tests {
_v: Vec<T>,
_s: Vec<S>,
}
let data: Data<i32, &str> = Data {
let mut data: Data<i32, &str> = Data {
_x: 12,
_y: "hello".to_string(),
_v: vec![1, 2, 3],
Expand All @@ -828,7 +818,7 @@ mod tests {
) -> Result<Vec<WasmValue>, HostFuncError> {
println!("Rust: Entering Rust function real_add");

let host_data = unsafe { Box::from_raw(data as *mut T) };
let host_data = data as *mut T;
println!("host_data: {:?}", host_data);

if input.len() != 2 {
Expand Down Expand Up @@ -865,7 +855,7 @@ mod tests {
let result = Function::create_sync_func(
&func_ty,
Box::new(real_add::<Data<i32, &str>>),
Some(Box::new(data)),
&mut data as *mut _,
0,
);
assert!(result.is_ok());
Expand Down Expand Up @@ -945,8 +935,12 @@ mod tests {
assert!(result.is_ok());
let func_ty = result.unwrap();
// create a host function
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand All @@ -973,7 +967,12 @@ mod tests {
assert!(result.is_ok());
let func_ty = result.unwrap();
// create a host function
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(func), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(func),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand All @@ -992,7 +991,12 @@ mod tests {
assert!(result.is_ok());
let func_ty = result.unwrap();
// create a host function
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand Down Expand Up @@ -1023,7 +1027,12 @@ mod tests {
assert!(result.is_ok());
let func_ty = result.unwrap();
// create a host function
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = Arc::new(Mutex::new(result.unwrap()));

Expand Down Expand Up @@ -1121,8 +1130,12 @@ mod tests {
let func_ty = result.unwrap();

// create a host function from the closure defined above
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand Down Expand Up @@ -1195,7 +1208,12 @@ mod tests {
let func_ty = result.unwrap();

// create a host function
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand Down Expand Up @@ -1322,7 +1340,7 @@ mod tests {
}
}

let data: Data<i32, &str> = Data {
let mut data: Data<i32, &str> = Data {
_x: 12,
_y: "hello".to_string(),
_v: vec![1, 2, 3],
Expand Down Expand Up @@ -1359,8 +1377,7 @@ mod tests {
let func_ty = result.unwrap();

// create an async host function
let result =
Function::create_async_func(&func_ty, Box::new(c), Some(Box::new(data)), 0);
let result = Function::create_async_func(&func_ty, Box::new(c), &mut data, 0);
assert!(result.is_ok());
let async_hello_func = result.unwrap();

Expand Down Expand Up @@ -1427,7 +1444,7 @@ mod tests {
_v: Vec<T>,
_s: Vec<S>,
}
let data: Data<i32, &str> = Data {
let mut data: Data<i32, &str> = Data {
_x: 12,
_y: "hello".to_string(),
_v: vec![1, 2, 3],
Expand Down Expand Up @@ -1465,7 +1482,7 @@ mod tests {
let result = Function::create_async_func(
&func_ty,
Box::new(f::<Data<i32, &str>>),
Some(Box::new(data)),
&mut data as _,
0,
);
assert!(result.is_ok());
Expand Down
7 changes: 6 additions & 1 deletion crates/wasmedge-sys/src/instance/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,12 @@ mod tests {
let result = FuncType::create([ValType::ExternRef, ValType::I32], [ValType::I32]);
assert!(result.is_ok());
let func_ty = result.unwrap();
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());

assert_eq!(HOST_FUNCS.read().len(), 1);
Expand Down
7 changes: 6 additions & 1 deletion crates/wasmedge-sys/src/instance/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@ mod tests {
assert!(result.is_ok());
let func_ty = result.unwrap();
// create a host function
let result = Function::create_sync_func::<NeverType>(&func_ty, Box::new(real_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(real_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();

Expand Down
48 changes: 36 additions & 12 deletions crates/wasmedge-sys/src/statistics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,12 @@ mod tests {
let result =
FuncType::create(vec![ValType::ExternRef, ValType::I32], vec![ValType::I32]);
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_add), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_add),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();
import.add_func("func-add", host_func);
Expand All @@ -472,8 +476,12 @@ mod tests {
let result =
FuncType::create(vec![ValType::ExternRef, ValType::I32], vec![ValType::I32]);
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_sub), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_sub),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();
import.add_func("func-sub", host_func);
Expand All @@ -482,8 +490,12 @@ mod tests {
let result =
FuncType::create(vec![ValType::ExternRef, ValType::I32], vec![ValType::I32]);
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_mul), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_mul),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();
import.add_func("func-mul", host_func);
Expand All @@ -492,8 +504,12 @@ mod tests {
let result =
FuncType::create(vec![ValType::ExternRef, ValType::I32], vec![ValType::I32]);
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_div), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_div),
std::ptr::null_mut(),
0,
);
assert!(result.is_ok());
let host_func = result.unwrap();
import.add_func("func-div", host_func);
Expand All @@ -502,17 +518,25 @@ mod tests {
let result = FuncType::create([], [ValType::I32]);
assert!(result.is_ok());
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_term), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_term),
std::ptr::null_mut(),
0,
);
let host_func = result.unwrap();
import.add_func("func-term", host_func);

// add host function: "func-fail"
let result = FuncType::create([], [ValType::I32]);
assert!(result.is_ok());
let func_ty = result.unwrap();
let result =
Function::create_sync_func::<NeverType>(&func_ty, Box::new(extern_fail), None, 0);
let result = Function::create_sync_func::<NeverType>(
&func_ty,
Box::new(extern_fail),
std::ptr::null_mut(),
0,
);
let host_func = result.unwrap();
import.add_func("func-fail", host_func);

Expand Down
Loading