diff --git a/crates/wasmedge-sys/src/async/fiber.rs b/crates/wasmedge-sys/src/async/fiber.rs index f240b2dab..9380e2d00 100644 --- a/crates/wasmedge-sys/src/async/fiber.rs +++ b/crates/wasmedge-sys/src/async/fiber.rs @@ -19,6 +19,8 @@ impl<'a> FiberFuture<'a> { /// /// # Arguments /// + /// * `async_state` - Used to store asynchronous state at run time. + /// /// * `func` - The function to execute. /// /// # Error @@ -106,7 +108,7 @@ pub(crate) struct TimeoutFiberFuture<'a> { fiber: Fiber<'a, Result<(), ()>, (), Result<(), ()>>, current_suspend: *mut *const Suspend, (), Result<(), ()>>, current_poll_cx: *mut *mut Context<'static>, - timeout_sec: u64, + deadline: std::time::SystemTime, } impl<'a> TimeoutFiberFuture<'a> { @@ -116,7 +118,9 @@ impl<'a> TimeoutFiberFuture<'a> { /// /// * `func` - The function to execute. /// - /// * `timeout_sec` - The maximum execution time in seconds for the function instance. + /// * `async_state` - Used to store asynchronous state at run time. + /// + /// * `deadline` - The deadline the function to be run. /// /// # Error /// @@ -124,7 +128,7 @@ impl<'a> TimeoutFiberFuture<'a> { pub(crate) async fn on_fiber( async_state: &AsyncState, func: impl FnOnce() -> R + Send, - timeout_sec: u64, + deadline: std::time::SystemTime, ) -> Result { let mut slot = None; @@ -150,7 +154,7 @@ impl<'a> TimeoutFiberFuture<'a> { fiber, current_suspend, current_poll_cx, - timeout_sec, + deadline, } }; @@ -185,8 +189,15 @@ impl<'a> Future for TimeoutFiberFuture<'a> { if libc::timer_create(libc::CLOCK_REALTIME, &mut sev, &mut timerid) < 0 { return Poll::Ready(Err(())); } + + let timeout = match self.deadline.duration_since(std::time::SystemTime::now()) { + Ok(timeout) => timeout.max(std::time::Duration::from_millis(100)), + Err(_) => return Poll::Ready(Err(())), + }; + let mut value: libc::itimerspec = std::mem::zeroed(); - value.it_value.tv_sec = self.timeout_sec as i64; + value.it_value.tv_sec = timeout.as_secs() as _; + value.it_value.tv_nsec = timeout.subsec_nanos() as _; if libc::timer_settime(timerid, 0, &value, std::ptr::null_mut()) < 0 { libc::timer_delete(timerid); return Poll::Ready(Err(())); diff --git a/crates/wasmedge-sys/src/executor.rs b/crates/wasmedge-sys/src/executor.rs index 5732a60b8..e506ebe2f 100644 --- a/crates/wasmedge-sys/src/executor.rs +++ b/crates/wasmedge-sys/src/executor.rs @@ -190,7 +190,7 @@ impl Executor { /// /// * `params` - The arguments to pass to the function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Errors /// @@ -201,7 +201,7 @@ impl Executor { &self, func: &Function, params: impl IntoIterator, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { use wasmedge_types::error; @@ -231,7 +231,8 @@ impl Executor { ))); } let mut value: libc::itimerspec = std::mem::zeroed(); - value.it_value.tv_sec = timeout as i64; + value.it_value.tv_sec = timeout.as_secs() as _; + value.it_value.tv_nsec = timeout.subsec_nanos() as _; if libc::timer_settime(timerid, 0, &value, std::ptr::null_mut()) < 0 { libc::timer_delete(timerid); return Err(Box::new(error::WasmEdgeError::Operation( @@ -267,6 +268,8 @@ impl Executor { /// /// # Arguments /// + /// * `async_state` - Used to store asynchronous state at run time. + /// /// * `func` - The function instance to run. /// /// * `params` - The arguments to pass to the function. @@ -291,11 +294,13 @@ impl Executor { /// /// # Arguments /// + /// * `async_state` - Used to store asynchronous state at run time. + /// /// * `func` - The function instance to run. /// /// * `params` - The arguments to pass to the function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Errors /// @@ -307,10 +312,11 @@ impl Executor { async_state: &AsyncState, func: &mut Function, params: impl IntoIterator + Send, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { use wasmedge_types::error; - TimeoutFiberFuture::on_fiber(async_state, || self.call_func(func, params), timeout) + let ldd = std::time::SystemTime::now() + timeout; + TimeoutFiberFuture::on_fiber(async_state, || self.call_func(func, params), ldd) .await .map_err(|_| Box::new(error::WasmEdgeError::ExecuteTimeout))? } @@ -357,6 +363,8 @@ impl Executor { /// /// # Arguments /// + /// * `async_state` - Used to store asynchronous state at run time. + /// /// * `func_ref` - The function reference instance to run. /// /// * `params` - The arguments to pass to the function. diff --git a/src/async/vm.rs b/src/async/vm.rs index 66aebed58..e135df6b9 100644 --- a/src/async/vm.rs +++ b/src/async/vm.rs @@ -185,7 +185,7 @@ impl<'inst, T: ?Sized + Send + AsyncInst> Vm<'inst, T> { /// /// * `args` - The arguments to be passed to the target wasm function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Error /// @@ -196,7 +196,7 @@ impl<'inst, T: ?Sized + Send + AsyncInst> Vm<'inst, T> { mod_name: Option<&str>, func_name: impl AsRef, args: impl IntoIterator + Send, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { let (mut func, executor) = match mod_name { Some(mod_name) => { diff --git a/src/executor.rs b/src/executor.rs index 629e54bf2..ebf2cb48d 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -67,7 +67,7 @@ impl Executor { /// /// * `params` - The arguments to pass to the function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Errors /// @@ -78,14 +78,10 @@ impl Executor { &self, func: &Func, params: impl IntoIterator, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { - if timeout > 0 { - self.inner - .call_func_with_timeout(&func.inner, params, timeout) - } else { - self.inner.call_func(&func.inner, params) - } + self.inner + .call_func_with_timeout(&func.inner, params, timeout) } /// Asynchronously runs a host function instance and returns the results. @@ -116,11 +112,13 @@ impl Executor { /// /// # Arguments /// + /// * `async_state` - Used to store asynchronous state at run time. + /// /// * `func` - The function instance to run. /// /// * `params` - The arguments to pass to the function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Errors /// @@ -132,7 +130,7 @@ impl Executor { async_state: &AsyncState, func: &Func, params: impl IntoIterator + Send, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { self.inner .call_func_async_with_timeout(async_state, &func.inner, params, timeout) diff --git a/src/vm.rs b/src/vm.rs index 99ee622ca..5565a6d5f 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -177,7 +177,7 @@ impl<'inst, T: ?Sized + SyncInst> Vm<'inst, T> { /// /// * `args` - The arguments to be passed to the target wasm function. /// - /// * `timeout` - The maximum execution time (in seconds) of the function to be run. + /// * `timeout` - The maximum execution time of the function to be run. /// /// # Error /// @@ -188,7 +188,7 @@ impl<'inst, T: ?Sized + SyncInst> Vm<'inst, T> { mod_name: Option<&str>, func_name: impl AsRef, args: impl IntoIterator, - timeout: u64, + timeout: std::time::Duration, ) -> WasmEdgeResult> { let (mut func, executor) = match mod_name { Some(mod_name) => {