fn poll_wakeups()

in quic/s2n-quic-transport/src/endpoint/mod.rs [172:259]


    fn poll_wakeups<C: Clock>(
        &mut self,
        cx: &mut task::Context<'_>,
        clock: &C,
    ) -> Poll<Result<usize, s2n_quic_core::endpoint::CloseError>> {
        if self.close_handle.poll_interest().is_ready() // poll for close interest
            && self.connections.is_empty() // wait for all connections to close gracefully
            && self.connections.is_open()
        {
            // transition to close state
            self.close_handle.close();

            // stop accepting new connections and prepare to close the endpoint
            self.connections.close();
        }

        // Drop the endpoint if there is no more progress to be made.
        if !self.connections.is_open() {
            return Poll::Ready(Err(s2n_quic_core::endpoint::CloseError));
        }

        self.wakeup_queue
            .poll_pending_wakeups(&mut self.dequeued_wakeups, cx);

        let mut now: Option<Timestamp> = None;
        let mut wakeup_count = self.dequeued_wakeups.len();
        let close_packet_buffer = &mut self.close_packet_buffer;
        let endpoint_context = self.config.context();

        for internal_id in self.dequeued_wakeups.drain(..) {
            self.connections.with_connection(internal_id, |conn| {
                let timestamp = match now {
                    Some(now) => now,
                    _ => {
                        let time = clock.get_time();
                        now = Some(time);
                        time
                    }
                };

                if let Err(error) = conn.on_wakeup(
                    timestamp,
                    endpoint_context.event_subscriber,
                    endpoint_context.datagram,
                    endpoint_context.dc,
                    endpoint_context.connection_limits,
                ) {
                    conn.close(
                        error,
                        endpoint_context.connection_close_formatter,
                        close_packet_buffer,
                        timestamp,
                        endpoint_context.event_subscriber,
                        endpoint_context.packet_interceptor,
                    );
                }
            });
        }

        // try to open connection requests from the application
        if Cfg::ENDPOINT_TYPE.is_client() {
            loop {
                match self.connections.poll_connection_request(cx) {
                    Poll::Pending => break,
                    Poll::Ready(Some(request)) => {
                        wakeup_count += 1;

                        let time = clock.get_time();
                        if let Err(err) = self.create_client_connection(request, time) {
                            // TODO report that the connection was not successfully created
                            // TODO emit event
                            dbg!(err);
                        }
                    }
                    Poll::Ready(None) => {
                        // the client handle has been dropped so break from loop
                        break;
                    }
                }
            }
        }

        if wakeup_count > 0 {
            Poll::Ready(Ok(wakeup_count))
        } else {
            Poll::Pending
        }
    }