Reorder socket locks

This commit is contained in:
Ruihan Li 2025-04-20 16:43:38 +08:00 committed by Tate, Hongliang Tian
parent 961ad73847
commit 96e62b8fa5
4 changed files with 20 additions and 16 deletions

View File

@ -47,8 +47,10 @@ impl OptionSet {
}
pub struct DatagramSocket {
options: RwLock<OptionSet>,
// Lock order: `inner` first, `options` second
inner: RwLock<Takeable<Inner>, PreemptDisabled>,
options: RwLock<OptionSet>,
is_nonblocking: AtomicBool,
pollee: Pollee,
}
@ -101,9 +103,9 @@ impl DatagramSocket {
let unbound_datagram = UnboundDatagram::new();
Arc::new(Self {
inner: RwLock::new(Takeable::new(Inner::Unbound(unbound_datagram))),
options: RwLock::new(OptionSet::new()),
is_nonblocking: AtomicBool::new(is_nonblocking),
pollee: Pollee::new(),
options: RwLock::new(OptionSet::new()),
})
}
@ -257,8 +259,8 @@ impl Socket for DatagramSocket {
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
let endpoint = socket_addr.try_into()?;
let can_reuse = self.options.read().socket.reuse_addr();
let mut inner = self.inner.write();
let can_reuse = self.options.read().socket.reuse_addr();
inner.borrow_result(|owned_inner| {
let bound_datagram = match owned_inner.bind(
&endpoint,
@ -373,10 +375,10 @@ impl Socket for DatagramSocket {
}
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
let inner = self.inner.read();
let mut options = self.options.write();
let mut inner = self.inner.write();
match options.socket.set_option(option, inner.as_mut()) {
match options.socket.set_option(option, inner.as_ref()) {
Err(e) => Err(e),
Ok(need_iface_poll) => {
let iface_to_poll = need_iface_poll

View File

@ -54,7 +54,7 @@ impl IpOptionSet {
pub(super) fn set_option(
&mut self,
option: &dyn SocketOption,
socket: &mut dyn SetIpLevelOption,
socket: &dyn SetIpLevelOption,
) -> Result<NeedIfacePoll> {
match_sock_option_ref!(option, {
ip_tos: Tos => {

View File

@ -58,8 +58,10 @@ pub(in crate::net) use self::observer::StreamObserver;
pub use self::util::CongestionControl;
pub struct StreamSocket {
options: RwLock<OptionSet>,
// Lock order: `state` first, `options` second
state: RwLock<Takeable<State>, PreemptDisabled>,
options: RwLock<OptionSet>,
is_nonblocking: AtomicBool,
pollee: Pollee,
}
@ -102,8 +104,8 @@ impl StreamSocket {
pub fn new(is_nonblocking: bool) -> Arc<Self> {
let init_stream = InitStream::new();
Arc::new(Self {
options: RwLock::new(OptionSet::new()),
state: RwLock::new(Takeable::new(State::Init(init_stream))),
options: RwLock::new(OptionSet::new()),
is_nonblocking: AtomicBool::new(is_nonblocking),
pollee: Pollee::new(),
})
@ -190,11 +192,11 @@ impl StreamSocket {
fn start_connect(&self, remote_endpoint: &IpEndpoint) -> Option<Result<()>> {
let is_nonblocking = self.is_nonblocking();
let mut state = self.write_updated_state();
let options = self.options.read();
let raw_option = options.raw();
let mut state = self.write_updated_state();
let (result_or_block, iface_to_poll) = state.borrow_result(|mut owned_state| {
let mut init_stream = match owned_state {
State::Init(init_stream) => init_stream,
@ -426,12 +428,12 @@ impl Socket for StreamSocket {
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
let endpoint = socket_addr.try_into()?;
let can_reuse = self.options.read().socket.reuse_addr();
let mut state = self.write_updated_state();
let State::Init(init_stream) = state.as_mut() else {
return_errno_with_message!(Errno::EINVAL, "the socket is already bound to an address");
};
let can_reuse = self.options.read().socket.reuse_addr();
init_stream.bind(&endpoint, can_reuse)
}
@ -446,11 +448,11 @@ impl Socket for StreamSocket {
}
fn listen(&self, backlog: usize) -> Result<()> {
let mut state = self.write_updated_state();
let options = self.options.read();
let raw_option = options.raw();
let mut state = self.write_updated_state();
state.borrow_result(|owned_state| {
let init_stream = match owned_state {
State::Init(init_stream) => init_stream,
@ -665,8 +667,8 @@ impl Socket for StreamSocket {
}
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
let mut options = self.options.write();
let mut state = self.write_updated_state();
let mut options = self.options.write();
// Deal with socket-level options
let need_iface_poll = match options.socket.set_option(option, state.as_mut()) {

View File

@ -91,7 +91,7 @@ impl SocketOptionSet {
pub fn set_option(
&mut self,
option: &dyn SocketOption,
socket: &mut dyn SetSocketLevelOption,
socket: &dyn SetSocketLevelOption,
) -> Result<NeedIfacePoll> {
match_sock_option_ref!(option, {
socket_recv_buf: RecvBuf => {