mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
Add a method to add data to an event loop directly
Avoids Send entirely
This commit is contained in:
parent
8daac0347d
commit
164193fe82
@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell};
|
|||||||
use std::io::{self, ErrorKind};
|
use std::io::{self, ErrorKind};
|
||||||
use std::marker;
|
use std::marker;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
@ -47,6 +48,12 @@ pub struct Loop {
|
|||||||
// `timeouts` slab.
|
// `timeouts` slab.
|
||||||
timer_wheel: RefCell<TimerWheel<usize>>,
|
timer_wheel: RefCell<TimerWheel<usize>>,
|
||||||
timeouts: RefCell<Slab<(Timeout, TimeoutState), usize>>,
|
timeouts: RefCell<Slab<(Timeout, TimeoutState), usize>>,
|
||||||
|
|
||||||
|
// A `Loop` cannot be sent to other threads as it's used as a proxy for data
|
||||||
|
// that belongs to the thread the loop was running on at some point. In
|
||||||
|
// other words, the safety of `DropBox` below relies on loops not crossing
|
||||||
|
// threads.
|
||||||
|
_marker: marker::PhantomData<Rc<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MioSender {
|
struct MioSender {
|
||||||
@ -128,6 +135,7 @@ impl Loop {
|
|||||||
dispatch: RefCell::new(Slab::new_starting_at(1, SLAB_CAPACITY)),
|
dispatch: RefCell::new(Slab::new_starting_at(1, SLAB_CAPACITY)),
|
||||||
timeouts: RefCell::new(Slab::new_starting_at(0, SLAB_CAPACITY)),
|
timeouts: RefCell::new(Slab::new_starting_at(0, SLAB_CAPACITY)),
|
||||||
timer_wheel: RefCell::new(TimerWheel::new()),
|
timer_wheel: RefCell::new(TimerWheel::new()),
|
||||||
|
_marker: marker::PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +151,22 @@ impl Loop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `LoopData<A>` handle by associating data to be directly
|
||||||
|
/// stored by this event loop.
|
||||||
|
///
|
||||||
|
/// This function is useful for when storing non-`Send` data inside of a
|
||||||
|
/// future. The `LoopData<A>` handle is itself `Send + 'static` regardless
|
||||||
|
/// of the underlying `A`. That is, for example, you can create a handle to
|
||||||
|
/// some data that contains an `Rc`, for example.
|
||||||
|
pub fn add_loop_data<A>(&self, a: A) -> LoopData<A>
|
||||||
|
where A: Any,
|
||||||
|
{
|
||||||
|
LoopData {
|
||||||
|
data: DropBox::new_on(a, self),
|
||||||
|
handle: self.handle(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs a future until completion, driving the event loop while we're
|
/// Runs a future until completion, driving the event loop while we're
|
||||||
/// otherwise waiting for the future to complete.
|
/// otherwise waiting for the future to complete.
|
||||||
///
|
///
|
||||||
@ -776,7 +800,7 @@ impl<A: Any> Drop for LoopData<A> {
|
|||||||
mod dropbox {
|
mod dropbox {
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use super::CURRENT_LOOP;
|
use super::{CURRENT_LOOP, Loop};
|
||||||
|
|
||||||
pub struct DropBox<A: ?Sized> {
|
pub struct DropBox<A: ?Sized> {
|
||||||
id: usize,
|
id: usize,
|
||||||
@ -801,6 +825,16 @@ mod dropbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `DropBox` pinned to the thread of `Loop`.
|
||||||
|
///
|
||||||
|
/// Will panic if `CURRENT_LOOP` isn't set.
|
||||||
|
pub fn new_on<A: Any>(a: A, lp: &Loop) -> DropBox<A> {
|
||||||
|
DropBox {
|
||||||
|
id: lp.id,
|
||||||
|
inner: Some(Box::new(a)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Downcasts this `DropBox` to the type specified.
|
/// Downcasts this `DropBox` to the type specified.
|
||||||
///
|
///
|
||||||
/// Normally this always succeeds as it's a static assertion that we
|
/// Normally this always succeeds as it's a static assertion that we
|
||||||
|
Loading…
x
Reference in New Issue
Block a user