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
}
}