diff --git a/kernel/aster-nix/src/net/socket/unix/stream/listener.rs b/kernel/aster-nix/src/net/socket/unix/stream/listener.rs index 3d746c870..727dc1bdc 100644 --- a/kernel/aster-nix/src/net/socket/unix/stream/listener.rs +++ b/kernel/aster-nix/src/net/socket/unix/stream/listener.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 +use core::sync::atomic::{AtomicUsize, Ordering}; + use keyable_arc::KeyableWeak; use super::{connected::Connected, endpoint::Endpoint, UnixStreamSocket}; @@ -38,6 +40,11 @@ impl Listener { Ok((socket, peer_addr)) } + pub(super) fn listen(&self, backlog: usize) -> Result<()> { + self.backlog.set_backlog(backlog); + Ok(()) + } + pub(super) fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { self.backlog.poll(mask, poller) } @@ -135,7 +142,7 @@ impl BacklogTable { struct Backlog { addr: UnixSocketAddrBound, pollee: Pollee, - backlog: usize, + backlog: AtomicUsize, incoming_endpoints: Mutex>, } @@ -144,7 +151,7 @@ impl Backlog { Self { addr, pollee: Pollee::new(IoEvents::empty()), - backlog, + backlog: AtomicUsize::new(backlog), incoming_endpoints: Mutex::new(VecDeque::with_capacity(backlog)), } } @@ -155,7 +162,7 @@ impl Backlog { fn push_incoming(&self, endpoint: Endpoint) -> Result<()> { let mut endpoints = self.incoming_endpoints.lock(); - if endpoints.len() >= self.backlog { + if endpoints.len() >= self.backlog.load(Ordering::Relaxed) { return_errno_with_message!(Errno::ECONNREFUSED, "incoming_endpoints is full"); } endpoints.push_back(endpoint); @@ -173,6 +180,10 @@ impl Backlog { .ok_or_else(|| Error::with_message(Errno::EAGAIN, "no pending connection is available")) } + fn set_backlog(&self, backlog: usize) { + self.backlog.store(backlog, Ordering::Relaxed); + } + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { // Lock to avoid any events may change pollee state when we poll let _lock = self.incoming_endpoints.lock(); diff --git a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs index 53c51ff26..3ae2f7254 100644 --- a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs +++ b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs @@ -242,11 +242,11 @@ impl Socket for UnixStreamSocket { "the socket is not bound", ))? .clone(), - State::Listen(_) => { - return_errno_with_message!(Errno::EINVAL, "the socket is already listening") + State::Listen(listen) => { + return listen.listen(backlog); } State::Connected(_) => { - return_errno_with_message!(Errno::EISCONN, "the socket is already connected") + return_errno_with_message!(Errno::EINVAL, "the socket is connected") } }; diff --git a/test/apps/network/unix_err.c b/test/apps/network/unix_err.c index 6e8d17882..00aa42888 100644 --- a/test/apps/network/unix_err.c +++ b/test/apps/network/unix_err.c @@ -218,3 +218,15 @@ FN_TEST(connect) EISCONN); } END_TEST() + +FN_TEST(listen) +{ + TEST_ERRNO(listen(sk_unbound, 10), EINVAL); + + TEST_SUCC(listen(sk_listen, 10)); + + TEST_ERRNO(listen(sk_connected, 10), EINVAL); + + TEST_ERRNO(listen(sk_accepted, 10), EINVAL); +} +END_TEST()