[−][src]Struct async_executors::TokioCt
feature="tokio_ct"
only.An executor that uses a tokio::runtime::Runtime
with the basic scheduler
and a tokio::task::LocalSet
. Can spawn !Send
futures.
You can obtain a wrapper to tokio::runtime::Handle
through TokioCt::handle
. That can be used to send a future
from another thread to run on the TokioCt
executor.
Creation of the runtime
You create the wrapper through the TryFrom
impl for tokio::runtime::Builder
. This allows you to configure
the tokio runtime that will be used. Setting threaded_scheduler
on it will be void and overwritten. core_threads
also makes no sense. You can choose any other configuration, like whether to have a reactor and a timer.
// Make sure to set the `tokio_ct` feature on async_executors. The // following example also requires the feature `spawn_handle`. // use { async_executors :: { TokioCt, LocalSpawnHandleExt } , tokio :: { runtime::Builder } , std :: { convert::TryFrom, rc::Rc } , }; let exec = TokioCt::try_from( &mut Builder::new() ).expect( "create tokio runtime" ); // block_on takes a &self, so if you need to `async move`, // just clone it for use inside the async block. // exec.block_on( async { let not_send = async { let rc = Rc::new(()); }; // We can spawn !Send futures here. // let join_handle = exec.spawn_handle_local( not_send ).expect( "spawn" ); join_handle.await; });
Unwind Safety.
When a future spawned on this wrapper panics, the thread will unwind until the block_on
, not above.
You must only spawn futures to this API that are unwind safe. Tokio will wrap the task running from block_on
in
std::panic::AssertUnwindSafe
and wrap the poll invocation with std::panic::catch_unwind
.
They reason that this is fine because they require Send + 'static
on the task. As far
as I can tell this is wrong. Unwind safety can be circumvented in several ways even with
Send + 'static
(eg. parking_lot::Mutex
is Send + 'static
but !UnwindSafe
).
You should make sure that if your future panics, no code that lives on after the top level task has unwound, nor any destructors called during the unwind can observe data in an inconsistent state.
Note that these are logic errors, not related to the class of problems that cannot happen in safe rust (memory safety, undefined behavior, unsoundness, data races, ...). See the relevant catch_unwind RFC and it's discussion threads for more info as well as the documentation of std::panic::UnwindSafe for more information.
Implementations
impl TokioCt
[src]
pub fn block_on<F: Future>(&self, f: F) -> F::Output
[src]
This is the entry point for this executor. Once this call returns, no remaining tasks shall be polled anymore.
However the tasks stay in the executor, so if you make a second call to block_on
with a new task, the older
tasks will start making progress again.
For simplicity, it's advised to just create top level task that you run through block_on
and make sure your
program is done when it returns.
Panics
This function will panic if it is called from an async context, including but not limited to making a nested call.
pub fn handle(&self) -> TokioHandle
[src]
Obtain a handle to this executor that can be send to another thread. This allows spawning
tasks on this executor from other threads, but as such requires those tasks to be Send
.
Wrapper around tokio::runtime::Handle
.
Trait Implementations
impl Clone for TokioCt
[src]
impl Debug for TokioCt
[src]
impl LocalSpawn for TokioCt
[src]
fn spawn_local_obj(
&self,
future: LocalFutureObj<'static, ()>
) -> Result<(), SpawnError>
[src]
&self,
future: LocalFutureObj<'static, ()>
) -> Result<(), SpawnError>
fn status_local(&self) -> Result<(), SpawnError>
[src]
impl<Out: 'static> LocalSpawnHandle<Out> for TokioCt
[src]
fn spawn_handle_local_obj(
&self,
future: LocalFutureObj<'static, Out>
) -> Result<JoinHandle<Out>, SpawnError>
[src]
&self,
future: LocalFutureObj<'static, Out>
) -> Result<JoinHandle<Out>, SpawnError>
impl Spawn for TokioCt
[src]
fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError>
[src]
fn status(&self) -> Result<(), SpawnError>
[src]
impl<Out: 'static + Send> SpawnHandle<Out> for TokioCt
[src]
fn spawn_handle_obj(
&self,
future: FutureObj<'static, Out>
) -> Result<JoinHandle<Out>, SpawnError>
[src]
&self,
future: FutureObj<'static, Out>
) -> Result<JoinHandle<Out>, SpawnError>
impl<'_> TryFrom<&'_ mut Builder> for TokioCt
[src]
Auto Trait Implementations
impl !RefUnwindSafe for TokioCt
impl !Send for TokioCt
impl !Sync for TokioCt
impl Unpin for TokioCt
impl !UnwindSafe for TokioCt
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T> Instrument for T
[src]
fn instrument(self, span: Span) -> Instrumented<Self>
[src]
fn in_current_span(self) -> Instrumented<Self>
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<Sp> LocalSpawnExt for Sp where
Sp: LocalSpawn + ?Sized,
[src]
Sp: LocalSpawn + ?Sized,
fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError> where
Fut: Future<Output = ()> + 'static,
[src]
Fut: Future<Output = ()> + 'static,
fn spawn_local_with_handle<Fut>(
&self,
future: Fut
) -> Result<RemoteHandle<<Fut as Future>::Output>, SpawnError> where
Fut: Future + 'static,
[src]
&self,
future: Fut
) -> Result<RemoteHandle<<Fut as Future>::Output>, SpawnError> where
Fut: Future + 'static,
impl<Sp> SpawnExt for Sp where
Sp: Spawn + ?Sized,
[src]
Sp: Spawn + ?Sized,
fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError> where
Fut: Future<Output = ()> + Send + 'static,
[src]
Fut: Future<Output = ()> + Send + 'static,
fn spawn_with_handle<Fut>(
&self,
future: Fut
) -> Result<RemoteHandle<<Fut as Future>::Output>, SpawnError> where
Fut: Future + Send + 'static,
<Fut as Future>::Output: Send,
[src]
&self,
future: Fut
) -> Result<RemoteHandle<<Fut as Future>::Output>, SpawnError> where
Fut: Future + Send + 'static,
<Fut as Future>::Output: Send,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> WithSubscriber for T
[src]
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
[src]
S: Into<Dispatch>,