Skip to content

Conversation

@mehnazyunus
Copy link
Member

@mehnazyunus mehnazyunus commented Nov 4, 2025

Release Summary:

Resolved issues:

Description of changes:

  • Add manual future implementation and Box only if the initial send fails.
  • Decrypt initial packet before sending on the Unix domain socket.

Call-outs:

Added in comments.

Testing:

Checked that existing tests pass and ensured that CPU utilization is 0 when adding a sleep after sending streams in test_kernel_queue_full.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

let this = self.get_mut();

loop {
let mut guard = ready!(this.sender.socket_fd.poll_write_ready(cx))?;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From tokio docs about AsyncFd::poll_write_ready,
"Because these functions don’t create a future to hold their state, they have the limitation that only one task can wait on each direction (read or write) at a time."
Would this become an issue if we have multiple acceptor tasks sending to the same unix domain socket?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We'll need to see if we can use writable and perhaps have a fixed size allocation for the returned future... I'm not seeing a non-poll API with a named future return type in the tokio API.

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();

loop {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the docs, "On some platforms, the readiness detecting mechanism relies on edge-triggered notifications. This means that the OS will only notify Tokio when the file descriptor transitions from not-ready to ready. For this to work you should first try to read or write and only poll for readiness if that fails with an error of std::io::ErrorKind::WouldBlock."
Is this something we care about? I think this would mean we should try to send on the socket first.

.unwrap();
info!("Handshake completed");

let app_server = create_application_server(&unix_socket_path, test_event_subscriber.clone());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uds sender is now created on manager build (instead of on accepting a stream from the client), so we need the application receive socket to be created first.

@mehnazyunus mehnazyunus marked this pull request as ready for review November 6, 2025 22:06
@mehnazyunus mehnazyunus requested a review from a team as a code owner November 6, 2025 22:06
// Allocate a future on the heap only if initial send returns WouldBlock
let sender = this.sender.clone();
let packet = this.packet.clone();
let fd = this.fd_to_send.try_clone()?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think rather than cloning these, we'd probably want to make SendMsg an enum and switch it to a Future state, i.e., it would move out of these fields?

pub fn new(sender: Sender, packet: &[u8], fd_to_send: OwnedFd) -> SendMsg {
SendMsg {
sender,
packet: packet.to_vec(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the caller already has a Vec, can they just provide that to us?

@mehnazyunus mehnazyunus merged commit ceb587d into aws:main Nov 17, 2025
122 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants