dope_fiber/net/server/
accept.rs1use std::task;
2
3use dope::{
4 core::driver::route::{Identity, KeyTag},
5 net::wire,
6};
7
8use crate::{
9 abi, context,
10 manifold::network::listener::{self, conn},
11 net::{self, server},
12 wait,
13};
14
15pub enum Error<'d> {
17 Wait(wait::Error<'d>),
18 Listener(listener::AcceptError),
19}
20
21#[pin_project::pin_project]
22#[must_use = "a fiber does nothing unless it is driven"]
23pub struct Accept<'scope, 'w, 'd: 'w, W: wire::Spec + 'w, ID: Identity = KeyTag<0>> {
24 host: server::Handle<'scope, 'w, 'd, W, ID>,
25 #[pin]
26 waiter: wait::Waiter<'scope, 'd>,
27}
28
29impl<'scope, 'w, 'd: 'w, W: wire::Spec + 'w, ID: Identity> Accept<'scope, 'w, 'd, W, ID> {
30 pub(super) fn new(host: server::Handle<'scope, 'w, 'd, W, ID>) -> Self {
31 Self {
32 host,
33 waiter: wait::Waiter::new(),
34 }
35 }
36}
37
38impl<'scope, 'w, 'd: 'w, W: wire::Spec + 'w, ID: Identity> abi::Fiber<'d>
39 for Accept<'scope, 'w, 'd, W, ID>
40{
41 type Output = Result<net::Io<'scope, 'w, 'd, W, conn::Id<'d, ID>>, Error<'d>>;
42
43 fn poll(call: context::PollCall<'_, '_, 'd, Self>) -> task::Poll<Self::Output> {
44 use task::Poll;
45
46 let (this, context) = call.into_parts();
47 let this = this.project();
48 let waiter = this.waiter;
49 let Some((_, accepted)) = this.host.port.accepts.next::<0>() else {
50 if let Some(error) = this.host.watch.error() {
51 waiter.as_ref().unregister();
52 return Poll::Ready(Err(Error::Listener(error)));
53 }
54 return match this
55 .host
56 .port
57 .waiters
58 .try_register(waiter.as_ref(), context.as_ref())
59 {
60 Ok(()) => Poll::Pending,
61 Err(error) => Poll::Ready(Err(Error::Wait(error))),
62 };
63 };
64 waiter.as_ref().unregister();
65 Poll::Ready(Ok(net::Io::new(&this.host.port.connections, accepted)))
66 }
67}