mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-17 12:47:16 +00:00
Fix behavior in UNIX socket listen()
This commit is contained in:
parent
ac19a7e0e7
commit
a3d4748d6b
@ -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<VecDeque<Endpoint>>,
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
@ -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")
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user