pub struct ThreadBoundRunner<ThreadState> {
call_channel_tx: Sender<CallRequest<ThreadState>>,
}Expand description
A runner that takes a non-Send state and makes it Send compatible.
ThreadBoundRunner is designed to safely encapsulate a !Send state object by
pinning it to a single thread using spawn_local. It provides a Send API that
allows other threads to submit tasks (function pointers or closures) that operate on the
thread-bound state.
Tasks are queued via an internal channel and are executed sequentially on the owning thread.
§Example
use bitwarden_threading::ThreadBoundRunner;
struct State;
impl State {
pub async fn do_something(&self, some_input: i32) -> i32 {
return some_input;
}
}
let runner = ThreadBoundRunner::new(State);
let input = 42;
let output = runner.run_in_thread(move |state| async move {
return state.do_something(input).await;
}).await;
assert_eq!(output.unwrap(), 42);If you need mutable access to the state, you can wrap the ThreadState in a Mutex or
RwLock and use the run_in_thread method to lock it before accessing it.
§Example
use bitwarden_threading::ThreadBoundRunner;
use tokio::sync::Mutex;
struct State(i32);
let runner = ThreadBoundRunner::new(Mutex::new(State(0)));
runner.run_in_thread(|state| async move {
state.lock().await.0 += 1;
}).await;This pattern is useful for interacting with APIs or data structures that must remain on the same thread, such as GUI toolkits, WebAssembly contexts, or other thread-bound environments.
Fields§
§call_channel_tx: Sender<CallRequest<ThreadState>>Implementations§
Source§impl<ThreadState> ThreadBoundRunner<ThreadState>where
ThreadState: 'static,
impl<ThreadState> ThreadBoundRunner<ThreadState>where
ThreadState: 'static,
pub fn new(state: ThreadState) -> Self
Sourcepub async fn run_in_thread<F, Fut, Output>(
&self,
function: F,
) -> Result<Output, CallError>
pub async fn run_in_thread<F, Fut, Output>( &self, function: F, ) -> Result<Output, CallError>
Submit a task to be executed on the thread-bound state.
The provided function is executed on the thread that owns the internal ThreadState,
ensuring safe access to !Send data. Tasks are dispatched in the order they are
received, but because they are asynchronous, multiple tasks may be in-flight and running
concurrently if their futures yield.
§Returns
A future that resolves to the result of the function once it has been executed.
Trait Implementations§
Source§impl<ThreadState> Clone for ThreadBoundRunner<ThreadState>
Makes a clone of the runner handle.
impl<ThreadState> Clone for ThreadBoundRunner<ThreadState>
Makes a clone of the runner handle.
This creates another handle to the same underlying runner object. The underlying state is not duplicated; all clones refer to the same instance.