blocking_permit/macros.rs
1/// Attempt to dispatch a blocking operation, or otherwise obtain a permit and
2/// run on thread, returning the result of the closure.
3///
4/// This helper macro is intended for use in the context of an `async` block or
5/// function. It first attempts to dispatch the closure via
6/// [`dispatch_rx()`](crate::dispatch_rx) and await. If a dispatch pool is not
7/// registered on the current thread, it instead obtains a permit via
8/// [`blocking_permit_future()`](crate::blocking_permit_future) and awaits. If
9/// the _tokio-threaded_ feature is enabled, it will then run the closure via
10/// [`BlockingPermit::run()`](crate::BlockingPermit::run). Otherwise it will
11/// run the closure directly.
12///
13/// ## Usage
14///
15/// The closure should return a `Result<T, E>` where `From<Canceled>` is
16/// implemented for type E. The return type of the closure may be annotated as
17/// necessary. The closure may also be a `move` closure.
18///
19/// ```rust no_compile no_run
20/// async {
21/// dispatch_or_permit!(&semaphore, move || { /*.. blocking code..*/ });
22/// }
23/// ```
24#[macro_export] macro_rules! dispatch_or_permit {
25 ($semaphore:expr, $closure:expr) => {{
26 match $crate::dispatch_rx($closure) {
27 $crate::DispatchRx::Dispatch(disp) => {
28 disp .await?
29 }
30 $crate::DispatchRx::NotRegistered(cl) => {
31 let permit = $crate::blocking_permit_future($semaphore) .await?;
32 permit.run(cl)
33 }
34 }
35 }};
36}