mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 12:06:43 +00:00
Fix behavior in UNIX socket listen()
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
ac19a7e0e7
commit
a3d4748d6b
@ -1,5 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use keyable_arc::KeyableWeak;
|
use keyable_arc::KeyableWeak;
|
||||||
|
|
||||||
use super::{connected::Connected, endpoint::Endpoint, UnixStreamSocket};
|
use super::{connected::Connected, endpoint::Endpoint, UnixStreamSocket};
|
||||||
@ -38,6 +40,11 @@ impl Listener {
|
|||||||
Ok((socket, peer_addr))
|
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 {
|
pub(super) fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
||||||
self.backlog.poll(mask, poller)
|
self.backlog.poll(mask, poller)
|
||||||
}
|
}
|
||||||
@ -135,7 +142,7 @@ impl BacklogTable {
|
|||||||
struct Backlog {
|
struct Backlog {
|
||||||
addr: UnixSocketAddrBound,
|
addr: UnixSocketAddrBound,
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
backlog: usize,
|
backlog: AtomicUsize,
|
||||||
incoming_endpoints: Mutex<VecDeque<Endpoint>>,
|
incoming_endpoints: Mutex<VecDeque<Endpoint>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +151,7 @@ impl Backlog {
|
|||||||
Self {
|
Self {
|
||||||
addr,
|
addr,
|
||||||
pollee: Pollee::new(IoEvents::empty()),
|
pollee: Pollee::new(IoEvents::empty()),
|
||||||
backlog,
|
backlog: AtomicUsize::new(backlog),
|
||||||
incoming_endpoints: Mutex::new(VecDeque::with_capacity(backlog)),
|
incoming_endpoints: Mutex::new(VecDeque::with_capacity(backlog)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +162,7 @@ impl Backlog {
|
|||||||
|
|
||||||
fn push_incoming(&self, endpoint: Endpoint) -> Result<()> {
|
fn push_incoming(&self, endpoint: Endpoint) -> Result<()> {
|
||||||
let mut endpoints = self.incoming_endpoints.lock();
|
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");
|
return_errno_with_message!(Errno::ECONNREFUSED, "incoming_endpoints is full");
|
||||||
}
|
}
|
||||||
endpoints.push_back(endpoint);
|
endpoints.push_back(endpoint);
|
||||||
@ -173,6 +180,10 @@ impl Backlog {
|
|||||||
.ok_or_else(|| Error::with_message(Errno::EAGAIN, "no pending connection is available"))
|
.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 {
|
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
||||||
// Lock to avoid any events may change pollee state when we poll
|
// Lock to avoid any events may change pollee state when we poll
|
||||||
let _lock = self.incoming_endpoints.lock();
|
let _lock = self.incoming_endpoints.lock();
|
||||||
|
@ -242,11 +242,11 @@ impl Socket for UnixStreamSocket {
|
|||||||
"the socket is not bound",
|
"the socket is not bound",
|
||||||
))?
|
))?
|
||||||
.clone(),
|
.clone(),
|
||||||
State::Listen(_) => {
|
State::Listen(listen) => {
|
||||||
return_errno_with_message!(Errno::EINVAL, "the socket is already listening")
|
return listen.listen(backlog);
|
||||||
}
|
}
|
||||||
State::Connected(_) => {
|
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);
|
EISCONN);
|
||||||
}
|
}
|
||||||
END_TEST()
|
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()
|
||||||
|
Reference in New Issue
Block a user