tokio_threadpool/blocking/
mod.rs1use worker::Worker;
2
3use futures::{Async, Poll};
4use tokio_executor;
5
6use std::error::Error;
7use std::fmt;
8
9mod global;
10pub use self::global::blocking;
11#[doc(hidden)]
12pub use self::global::{set_default, with_default, DefaultGuard};
13
14pub struct BlockingError {
16 _p: (),
17}
18
19#[doc(hidden)]
26pub type BlockingImpl = fn(&mut dyn FnMut()) -> Poll<(), BlockingError>;
27
28fn default_blocking(f: &mut dyn FnMut()) -> Poll<(), BlockingError> {
29 let res = Worker::with_current(|worker| {
30 let worker = match worker {
31 Some(worker) => worker,
32 None => {
33 return Err(BlockingError::new());
34 }
35 };
36
37 worker.transition_to_blocking()
41 });
42
43 try_ready!(res);
45
46 tokio_executor::exit(move || (f)());
51
52 Worker::with_current(|worker| {
55 worker.unwrap().transition_from_blocking();
57 });
58
59 Ok(Async::Ready(()))
60}
61
62impl BlockingError {
63 #[doc(hidden)]
65 pub fn new() -> Self {
66 Self { _p: () }
67 }
68}
69
70impl fmt::Display for BlockingError {
71 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
72 write!(fmt, "{}", self.description())
73 }
74}
75
76impl fmt::Debug for BlockingError {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 f.debug_struct("BlockingError")
79 .field("reason", &self.description())
80 .finish()
81 }
82}
83
84impl Error for BlockingError {
85 fn description(&self) -> &str {
86 "`blocking` annotation used from outside the context of a thread pool"
87 }
88}