summaryrefslogtreecommitdiff
path: root/bindings/rs-timeout/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/rs-timeout/README.md')
-rw-r--r--bindings/rs-timeout/README.md163
1 files changed, 163 insertions, 0 deletions
diff --git a/bindings/rs-timeout/README.md b/bindings/rs-timeout/README.md
new file mode 100644
index 0000000..642f71e
--- /dev/null
+++ b/bindings/rs-timeout/README.md
@@ -0,0 +1,163 @@
+# bind-rs-timeout
+
+Rust binding for [timeout](https://github.com/wahern/timeout).
+
+It mainly includes two modules: `Timeout` and `TimeoutManager`. They respectively represent a timeout instance and a timeout manager.
+- `Timeout` is a timeout instance used to set the timeout time and bind the callback function (supporting closures).
+- `TimeoutManager` is used to manage timeout instances, update time, and trigger timeouts.
+
+## Usage
+
+To use the `Timeout` structure, you need to first create a `Timeout` instance and set the timeout callback function. Then add it to the `TimeoutManager` (ownership transferred to the C-side `TimeoutManager`), continuously update the `TimeoutManager` time, and call the `TimeoutManager::expired_timeouts` method to return the expired `Timeout` and execute the corresponding timeout callback function.
+
+```rust
+let to = Timeout::new(ToType::Default).unwrap(); // onetime type, relative timeout
+let to2 = Timeout::new(ToType::INT).unwrap(); // periodic type
+let mut tos = TimeoutManager::new(TIMEOUT_mHZ).unwrap();
+
+tos.update_time_rel(0); // relative time, tos.now = 0
+tos.add(to, 50); // onetime, expired time = tos.now + 50
+tos.add(to2, 100); // periodic, starting from tos.now, expiring every 100.
+
+tos.update_time_abs(150); // absolute time, tos.now = 150
+
+for to in tos.expired_timeouts() {
+ match to {
+ ToR::OneTime(temp) => {
+ // onetime type, Timeout, do something
+ // all flag has cleared assert!(to.is_expired()); will error
+ temp.run_cb();
+ }
+ ToR::Periodic(temp) => {
+ //periodic type, &Timeout, do something
+ // assert!(temp.is_periodic()); will work
+ }
+ };
+}
+```
+
+## Timeout
+
+`Timeout` is a structure representing a timeout instance used to set the timeout time. The structure contains multiple methods for setting the timeout callback function (supporting closures), checking the timeout status, deleting the timeout operation, etc.
+
+`Timeout` has three types:
+- `ToType::INT`: periodic timer, triggered repeatedly at a fixed interval, independent between each trigger, missing a trigger does not affect the next trigger time.
+- `ToType::ABS`: one-time timer, triggered once at the specified absolute time.
+- `ToType::Default`: one-time timer, triggered once after the specified relative time after adding the timer time point.
+
+### Method List
+
+The following is a list of methods for the `Timeout` structure:
+
+- `new(flags: ToType) -> Result<Timeout, &'static str>`: Create a new `Timeout` instance and set the timeout flag.
+- `is_pending(&self) -> bool`: Check whether the timeout has been registered and is on the timing wheel.
+- `is_expired(&self) -> bool`: Check whether the timeout has been registered and is on the expiration queue.
+- `is_periodic(&self) -> bool`: Check whether the timeout is periodic.
+- `delete(&mut self)`: Delete the timeout from the timing wheel or expiration queue.
+- `set_cb<T>(&mut self, cb: TimeoutCallBack<T>)`: Set the timeout callback function.
+- `set_cb_closure<F>(&mut self, closure: &mut F) where F: FnMut()`: Pass in a closure to set the timeout callback.
+- `run_cb(&self) -> bool`: Run the timeout callback function and return whether it has been executed successfully.
+
+### Adding Callbacks
+
+`Timeout` supports adding callbacks, which will be called by `run_cb` after expiration.
+
+The callback function of `Timeout` supports passing in C-compatible functions and `FnMut()` type closures.
+- When passing in a function, the function parameter is of type `&mut T`, and the return value is `()`.
+- When passing in a closure, the input parameter is `()`, and the return value is `()`.
+
+```rust
+pub struct Session { pub session_id: String,}
+let mut timeout = Timeout::new(ToType::Default).unwrap();
+
+extern "C" fn rust_callback(arg: &mut i32) {
+ println!("Callback executed with arg: {}", arg);
+}
+
+let mut binding = 11;
+let cb = TimeoutCallBack::new(rust_callback, &mut binding);
+
+timeout.set_cb(cb);
+timeout.run_cb();
+
+let mut session = Session { session_id: "123".to_string(),};
+
+timeout.set_cb_closure(&mut || {
+ println!("Callback executed with session_id: {}", session.session_id);
+ session.session_id = "456".to_string();
+ println!("Callback executed with session_id: {}", session.session_id);
+});
+
+timeout.run_cb();
+```
+
+Please note the lifetime of the callback.
+- When passing in a function, it is necessary to ensure that the lifetime of the function and its parameters is longer than the lifetime of `Timeout`, otherwise calling it will return false, indicating that the call failed.
+- When passing in a closure, it is necessary to ensure that the lifetime of the closure and its calling variables is longer than the lifetime of `Timeout`, otherwise calling it will return false, indicating that the call failed.
+
+## TimeoutManager
+
+`TimeoutManager` provides a `TimeoutManager` structure used to manage timeout operations. The structure contains multiple methods for creating, adding, deleting, and updating timeout operations.
+
+### Method List
+
+The following is a list of methods for the `TimeoutManager` structure:
+
+- `new(hz_set: timeout_t) -> Result<TimeoutManager, &'static str>`: Create a new `TimeoutManager` instance.
+- `close(&mut self)`: Close the `TimeoutManager` instance.
+- `update_time_rel(&mut self, time: timeout_t)`: Update the time, now = now + relative time.
+- `update_time_abs(&mut self, current_time: timeout_t)`: Update the time, now = absolute time.
+- `get_hz(&self) -> timeout_t`: Get the frequency of `TimeoutManager`.
+- `get_next_wait_time(&self) -> timeout_t`: Get the waiting time before the next timeout expires (definitely less than the actual waiting time). Returns `u64::MAX` if there is no waiting time.
+- `any_pending(&self) -> bool`: Check whether any timeout is waiting.
+- `any_expired(&self) -> bool`: Check whether any timeout has expired.
+- `check(&self) -> bool`: Check whether `TimeoutManager` is valid.
+
+Methods related to `Timeout`:
+
+- `add(&mut self, to: Timeout, timeout: timeout_t)`: Add a timeout, and transfer ownership to the C-side `TimeoutManager`. Depending on the type of the `to` parameter, the `timeout` parameter will have different effects.
+ - For the `ToType::INT` type, the `timeout` parameter is the periodic interval time. The start time is the current time of `TimeoutManager`.
+ - For the `ToType::ABS` type, it is triggered once at the specified absolute time.
+ - For the `ToType::Default` type, it is triggered once after the specified relative time after adding the timer time point.
+- `delete(&mut self, to: &mut Timeout)`: Delete the timeout.
+- `expired_timeouts(&mut self) -> ExpireIter`: Get the expired timeouts and return an iterator.
+ - For the corresponding `Timeout`, two types are returned: `ToR::OneTime` and `ToR::Periodic`.
+ - For non-periodic `Timeout`, the returned type is `Timeout`, and ownership is transferred to Rust.
+ - For periodic `Timeout`, its ownership is still on the C-side, so `&Timeout` type is returned.
+- `next_timeouts_pending(&mut self) -> NextIter`: Get the waiting `&Timeout` and return an iterator.
+- `next_timeouts_expired(&mut self) -> NextIter`: Get the expired `&Timeout` and return an iterator.
+- `next_timeouts_all(&mut self) -> NextIter`: Get all `&Timeout` and return an iterator.
+
+Note: `next_timeouts_xxx` is only a query method and does not perform any operations on the waiting or expired queues.
+
+Simple example
+
+```rust
+xxx
+let mut tos = TimeoutManager::new(TIMEOUT_mHZ).unwrap();
+xxx
+
+for to in tos.expired_timeouts() {
+ match to {
+ ToR::OneTime(temp) => {
+ // onetime type, Timeout, do something
+ temp.run_cb();
+ }
+ ToR::Periodic(temp) => {
+ //periodic type, &Timeout, do something
+ // temp.run_cb();
+ }
+ };
+}
+
+for to_ptr in tos.next_timeouts_expired() {
+ // do something
+ to_ptr.run_cb();
+}
+```
+
+## Others
+
+For periodic `Timeout`, its ownership is on the C side from the beginning of adding to `TimeoutManager` until `TimeoutManager` is closed. Therefore, the ownership of periodic `Timeout` cannot be obtained on the Rust side, only its reference can be obtained.
+
+A separate `delete_to_periodic(to: &Timeout)` is provided to remove periodic `Timeout` from `TimeoutManager`. \ No newline at end of file