mirror of https://github.com/fafhrd91/actix-net
Add AcceptContext type for passing Accept state to Acceptable trait
This commit is contained in:
parent
f3c9e465e0
commit
48ee38501a
|
@ -1,14 +1,19 @@
|
||||||
use std::{fmt, io};
|
use std::{fmt, io, marker::PhantomData};
|
||||||
|
|
||||||
use mio::{Registry, Token};
|
use mio::{Registry, Token};
|
||||||
|
|
||||||
|
use crate::waker_queue::WakerQueue;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
/// Trait define IO source that can be managed by [super::Accept].
|
/// Trait define IO source that can be managed by [super::Accept].
|
||||||
pub trait Acceptable: fmt::Debug {
|
pub trait Acceptable: fmt::Debug {
|
||||||
/// Type accepted from IO source.
|
/// Type accepted from IO source.
|
||||||
type Connection: Send + 'static;
|
type Connection: Send + 'static;
|
||||||
|
|
||||||
fn accept(&mut self) -> io::Result<Option<Self::Connection>>;
|
fn accept(
|
||||||
|
&mut self,
|
||||||
|
cx: &mut AcceptContext<'_, Self::Connection>,
|
||||||
|
) -> io::Result<Option<Self::Connection>>;
|
||||||
|
|
||||||
/// Register IO source to Acceptor [Registry](mio::Registry).
|
/// Register IO source to Acceptor [Registry](mio::Registry).
|
||||||
/// Self must impl [Source](mio::event::Source) trait.
|
/// Self must impl [Source](mio::event::Source) trait.
|
||||||
|
@ -18,3 +23,24 @@ pub trait Acceptable: fmt::Debug {
|
||||||
/// Self must impl [Source](mio::event::Source) trait.
|
/// Self must impl [Source](mio::event::Source) trait.
|
||||||
fn deregister(&mut self, registry: &Registry) -> io::Result<()>;
|
fn deregister(&mut self, registry: &Registry) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Context type of Accept thread. Expose Waker and possible other types to public.
|
||||||
|
pub struct AcceptContext<'a, C> {
|
||||||
|
waker: WakerQueue<C>,
|
||||||
|
_p: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, C> AcceptContext<'a, C> {
|
||||||
|
pub(super) fn new(waker: WakerQueue<C>) -> Self {
|
||||||
|
Self {
|
||||||
|
waker,
|
||||||
|
_p: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Make this public
|
||||||
|
pub(super) fn waker(&self) -> &WakerQueue<C> {
|
||||||
|
&self.waker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use loom::thread;
|
||||||
mod acceptable;
|
mod acceptable;
|
||||||
mod availability;
|
mod availability;
|
||||||
|
|
||||||
pub use acceptable::Acceptable;
|
pub use acceptable::{AcceptContext, Acceptable};
|
||||||
|
|
||||||
use std::{io, time::Duration};
|
use std::{io, time::Duration};
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ where
|
||||||
struct Accept<A: Acceptable> {
|
struct Accept<A: Acceptable> {
|
||||||
poll: Poll,
|
poll: Poll,
|
||||||
source: Box<[Source<A>]>,
|
source: Box<[Source<A>]>,
|
||||||
waker: WakerQueue<A::Connection>,
|
context: AcceptContext<'static, A::Connection>,
|
||||||
handles: Vec<WorkerHandleAccept<A::Connection>>,
|
handles: Vec<WorkerHandleAccept<A::Connection>>,
|
||||||
srv: Server,
|
srv: Server,
|
||||||
next: usize,
|
next: usize,
|
||||||
|
@ -143,7 +143,7 @@ where
|
||||||
// actix system.
|
// actix system.
|
||||||
let sys = System::current();
|
let sys = System::current();
|
||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name("actix-server acceptor".to_owned())
|
.name("actix-server accept".to_owned())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
System::set_current(sys);
|
System::set_current(sys);
|
||||||
let source = source
|
let source = source
|
||||||
|
@ -168,10 +168,12 @@ where
|
||||||
avail.set_available(handle.idx(), true);
|
avail.set_available(handle.idx(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let context = AcceptContext::new(waker);
|
||||||
|
|
||||||
let accept = Accept {
|
let accept = Accept {
|
||||||
poll,
|
poll,
|
||||||
source,
|
source,
|
||||||
waker,
|
context,
|
||||||
handles,
|
handles,
|
||||||
srv,
|
srv,
|
||||||
next: 0,
|
next: 0,
|
||||||
|
@ -221,7 +223,7 @@ where
|
||||||
loop {
|
loop {
|
||||||
// take guard with every iteration so no new interest can be added
|
// take guard with every iteration so no new interest can be added
|
||||||
// until the current task is done.
|
// until the current task is done.
|
||||||
let mut guard = self.waker.guard();
|
let mut guard = self.context.waker().guard();
|
||||||
match guard.pop_front() {
|
match guard.pop_front() {
|
||||||
// worker notify it becomes available.
|
// worker notify it becomes available.
|
||||||
Some(WakerInterest::WorkerAvailable(idx)) => {
|
Some(WakerInterest::WorkerAvailable(idx)) => {
|
||||||
|
@ -363,8 +365,8 @@ where
|
||||||
fn accept(&mut self, token: usize) {
|
fn accept(&mut self, token: usize) {
|
||||||
while self.avail.available() {
|
while self.avail.available() {
|
||||||
let source = &mut self.source[token];
|
let source = &mut self.source[token];
|
||||||
|
let cx = &mut self.context;
|
||||||
match source.acceptable.accept() {
|
match source.acceptable.accept(cx) {
|
||||||
Ok(Some(io)) => {
|
Ok(Some(io)) => {
|
||||||
let conn = Conn { token, io };
|
let conn = Conn { token, io };
|
||||||
self.accept_one(conn);
|
self.accept_one(conn);
|
||||||
|
@ -384,7 +386,7 @@ where
|
||||||
source.timeout = Some(Instant::now() + Duration::from_millis(500));
|
source.timeout = Some(Instant::now() + Duration::from_millis(500));
|
||||||
|
|
||||||
// after the sleep a Timer interest is sent to Accept Poll
|
// after the sleep a Timer interest is sent to Accept Poll
|
||||||
let waker = self.waker.clone();
|
let waker = self.context.waker().clone();
|
||||||
System::current().arbiter().spawn(async move {
|
System::current().arbiter().spawn(async move {
|
||||||
sleep(Duration::from_millis(510)).await;
|
sleep(Duration::from_millis(510)).await;
|
||||||
waker.wake(WakerInterest::Timer);
|
waker.wake(WakerInterest::Timer);
|
||||||
|
|
|
@ -14,7 +14,7 @@ mod test_server;
|
||||||
mod waker_queue;
|
mod waker_queue;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
|
||||||
pub use self::accept::Acceptable;
|
pub use self::accept::{AcceptContext, Acceptable};
|
||||||
pub use self::builder::ServerBuilder;
|
pub use self::builder::ServerBuilder;
|
||||||
pub use self::server::Server;
|
pub use self::server::Server;
|
||||||
pub use self::service::ServiceFactory;
|
pub use self::service::ServiceFactory;
|
||||||
|
|
|
@ -15,13 +15,16 @@ use actix_rt::net::TcpStream;
|
||||||
use mio::net::TcpStream as MioTcpStream;
|
use mio::net::TcpStream as MioTcpStream;
|
||||||
use mio::{event::Source, Interest, Registry, Token};
|
use mio::{event::Source, Interest, Registry, Token};
|
||||||
|
|
||||||
use crate::accept::Acceptable;
|
use crate::accept::{AcceptContext, Acceptable};
|
||||||
|
|
||||||
/// impl Acceptable trait for [mio::net::TcpListener] so it can be managed by server and it's [mio::Poll] instance.
|
/// impl Acceptable trait for [mio::net::TcpListener] so it can be managed by server and it's [mio::Poll] instance.
|
||||||
impl Acceptable for MioTcpListener {
|
impl Acceptable for MioTcpListener {
|
||||||
type Connection = MioTcpStream;
|
type Connection = MioTcpStream;
|
||||||
|
|
||||||
fn accept(&mut self) -> io::Result<Option<Self::Connection>> {
|
fn accept(
|
||||||
|
&mut self,
|
||||||
|
_: &mut AcceptContext<'_, Self::Connection>,
|
||||||
|
) -> io::Result<Option<Self::Connection>> {
|
||||||
Self::accept(self).map(|stream| Some(stream.0))
|
Self::accept(self).map(|stream| Some(stream.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +52,10 @@ impl From<StdTcpListener> for MioListener {
|
||||||
impl Acceptable for MioListener {
|
impl Acceptable for MioListener {
|
||||||
type Connection = MioStream;
|
type Connection = MioStream;
|
||||||
|
|
||||||
fn accept(&mut self) -> io::Result<Option<Self::Connection>> {
|
fn accept(
|
||||||
|
&mut self,
|
||||||
|
_: &mut AcceptContext<'_, Self::Connection>,
|
||||||
|
) -> io::Result<Option<Self::Connection>> {
|
||||||
match *self {
|
match *self {
|
||||||
MioListener::Tcp(ref mut lst) => {
|
MioListener::Tcp(ref mut lst) => {
|
||||||
MioTcpListener::accept(lst).map(|stream| Some(MioStream::Tcp(stream.0)))
|
MioTcpListener::accept(lst).map(|stream| Some(MioStream::Tcp(stream.0)))
|
||||||
|
@ -157,7 +163,10 @@ mod unix_impl {
|
||||||
impl Acceptable for MioUnixListener {
|
impl Acceptable for MioUnixListener {
|
||||||
type Connection = MioUnixStream;
|
type Connection = MioUnixStream;
|
||||||
|
|
||||||
fn accept(&mut self) -> io::Result<Option<Self::Connection>> {
|
fn accept(
|
||||||
|
&mut self,
|
||||||
|
_: &mut AcceptContext<'_, Self::Connection>,
|
||||||
|
) -> io::Result<Option<Self::Connection>> {
|
||||||
Self::accept(self).map(|stream| Some(stream.0))
|
Self::accept(self).map(|stream| Some(stream.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue