mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Reorder socket locks
This commit is contained in:
parent
961ad73847
commit
96e62b8fa5
@ -47,8 +47,10 @@ impl OptionSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DatagramSocket {
|
pub struct DatagramSocket {
|
||||||
options: RwLock<OptionSet>,
|
// Lock order: `inner` first, `options` second
|
||||||
inner: RwLock<Takeable<Inner>, PreemptDisabled>,
|
inner: RwLock<Takeable<Inner>, PreemptDisabled>,
|
||||||
|
options: RwLock<OptionSet>,
|
||||||
|
|
||||||
is_nonblocking: AtomicBool,
|
is_nonblocking: AtomicBool,
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
}
|
}
|
||||||
@ -101,9 +103,9 @@ impl DatagramSocket {
|
|||||||
let unbound_datagram = UnboundDatagram::new();
|
let unbound_datagram = UnboundDatagram::new();
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
inner: RwLock::new(Takeable::new(Inner::Unbound(unbound_datagram))),
|
inner: RwLock::new(Takeable::new(Inner::Unbound(unbound_datagram))),
|
||||||
|
options: RwLock::new(OptionSet::new()),
|
||||||
is_nonblocking: AtomicBool::new(is_nonblocking),
|
is_nonblocking: AtomicBool::new(is_nonblocking),
|
||||||
pollee: Pollee::new(),
|
pollee: Pollee::new(),
|
||||||
options: RwLock::new(OptionSet::new()),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,8 +259,8 @@ impl Socket for DatagramSocket {
|
|||||||
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
|
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
|
||||||
let endpoint = socket_addr.try_into()?;
|
let endpoint = socket_addr.try_into()?;
|
||||||
|
|
||||||
let can_reuse = self.options.read().socket.reuse_addr();
|
|
||||||
let mut inner = self.inner.write();
|
let mut inner = self.inner.write();
|
||||||
|
let can_reuse = self.options.read().socket.reuse_addr();
|
||||||
inner.borrow_result(|owned_inner| {
|
inner.borrow_result(|owned_inner| {
|
||||||
let bound_datagram = match owned_inner.bind(
|
let bound_datagram = match owned_inner.bind(
|
||||||
&endpoint,
|
&endpoint,
|
||||||
@ -373,10 +375,10 @@ impl Socket for DatagramSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
|
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
|
||||||
|
let inner = self.inner.read();
|
||||||
let mut options = self.options.write();
|
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),
|
Err(e) => Err(e),
|
||||||
Ok(need_iface_poll) => {
|
Ok(need_iface_poll) => {
|
||||||
let iface_to_poll = need_iface_poll
|
let iface_to_poll = need_iface_poll
|
||||||
|
@ -54,7 +54,7 @@ impl IpOptionSet {
|
|||||||
pub(super) fn set_option(
|
pub(super) fn set_option(
|
||||||
&mut self,
|
&mut self,
|
||||||
option: &dyn SocketOption,
|
option: &dyn SocketOption,
|
||||||
socket: &mut dyn SetIpLevelOption,
|
socket: &dyn SetIpLevelOption,
|
||||||
) -> Result<NeedIfacePoll> {
|
) -> Result<NeedIfacePoll> {
|
||||||
match_sock_option_ref!(option, {
|
match_sock_option_ref!(option, {
|
||||||
ip_tos: Tos => {
|
ip_tos: Tos => {
|
||||||
|
@ -58,8 +58,10 @@ pub(in crate::net) use self::observer::StreamObserver;
|
|||||||
pub use self::util::CongestionControl;
|
pub use self::util::CongestionControl;
|
||||||
|
|
||||||
pub struct StreamSocket {
|
pub struct StreamSocket {
|
||||||
options: RwLock<OptionSet>,
|
// Lock order: `state` first, `options` second
|
||||||
state: RwLock<Takeable<State>, PreemptDisabled>,
|
state: RwLock<Takeable<State>, PreemptDisabled>,
|
||||||
|
options: RwLock<OptionSet>,
|
||||||
|
|
||||||
is_nonblocking: AtomicBool,
|
is_nonblocking: AtomicBool,
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
}
|
}
|
||||||
@ -102,8 +104,8 @@ impl StreamSocket {
|
|||||||
pub fn new(is_nonblocking: bool) -> Arc<Self> {
|
pub fn new(is_nonblocking: bool) -> Arc<Self> {
|
||||||
let init_stream = InitStream::new();
|
let init_stream = InitStream::new();
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
options: RwLock::new(OptionSet::new()),
|
|
||||||
state: RwLock::new(Takeable::new(State::Init(init_stream))),
|
state: RwLock::new(Takeable::new(State::Init(init_stream))),
|
||||||
|
options: RwLock::new(OptionSet::new()),
|
||||||
is_nonblocking: AtomicBool::new(is_nonblocking),
|
is_nonblocking: AtomicBool::new(is_nonblocking),
|
||||||
pollee: Pollee::new(),
|
pollee: Pollee::new(),
|
||||||
})
|
})
|
||||||
@ -190,11 +192,11 @@ impl StreamSocket {
|
|||||||
fn start_connect(&self, remote_endpoint: &IpEndpoint) -> Option<Result<()>> {
|
fn start_connect(&self, remote_endpoint: &IpEndpoint) -> Option<Result<()>> {
|
||||||
let is_nonblocking = self.is_nonblocking();
|
let is_nonblocking = self.is_nonblocking();
|
||||||
|
|
||||||
|
let mut state = self.write_updated_state();
|
||||||
|
|
||||||
let options = self.options.read();
|
let options = self.options.read();
|
||||||
let raw_option = options.raw();
|
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 (result_or_block, iface_to_poll) = state.borrow_result(|mut owned_state| {
|
||||||
let mut init_stream = match owned_state {
|
let mut init_stream = match owned_state {
|
||||||
State::Init(init_stream) => init_stream,
|
State::Init(init_stream) => init_stream,
|
||||||
@ -426,12 +428,12 @@ impl Socket for StreamSocket {
|
|||||||
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
|
fn bind(&self, socket_addr: SocketAddr) -> Result<()> {
|
||||||
let endpoint = socket_addr.try_into()?;
|
let endpoint = socket_addr.try_into()?;
|
||||||
|
|
||||||
let can_reuse = self.options.read().socket.reuse_addr();
|
|
||||||
let mut state = self.write_updated_state();
|
let mut state = self.write_updated_state();
|
||||||
|
|
||||||
let State::Init(init_stream) = state.as_mut() else {
|
let State::Init(init_stream) = state.as_mut() else {
|
||||||
return_errno_with_message!(Errno::EINVAL, "the socket is already bound to an address");
|
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)
|
init_stream.bind(&endpoint, can_reuse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,11 +448,11 @@ impl Socket for StreamSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn listen(&self, backlog: usize) -> Result<()> {
|
fn listen(&self, backlog: usize) -> Result<()> {
|
||||||
|
let mut state = self.write_updated_state();
|
||||||
|
|
||||||
let options = self.options.read();
|
let options = self.options.read();
|
||||||
let raw_option = options.raw();
|
let raw_option = options.raw();
|
||||||
|
|
||||||
let mut state = self.write_updated_state();
|
|
||||||
|
|
||||||
state.borrow_result(|owned_state| {
|
state.borrow_result(|owned_state| {
|
||||||
let init_stream = match owned_state {
|
let init_stream = match owned_state {
|
||||||
State::Init(init_stream) => init_stream,
|
State::Init(init_stream) => init_stream,
|
||||||
@ -665,8 +667,8 @@ impl Socket for StreamSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
|
fn set_option(&self, option: &dyn SocketOption) -> Result<()> {
|
||||||
let mut options = self.options.write();
|
|
||||||
let mut state = self.write_updated_state();
|
let mut state = self.write_updated_state();
|
||||||
|
let mut options = self.options.write();
|
||||||
|
|
||||||
// Deal with socket-level options
|
// Deal with socket-level options
|
||||||
let need_iface_poll = match options.socket.set_option(option, state.as_mut()) {
|
let need_iface_poll = match options.socket.set_option(option, state.as_mut()) {
|
||||||
|
@ -91,7 +91,7 @@ impl SocketOptionSet {
|
|||||||
pub fn set_option(
|
pub fn set_option(
|
||||||
&mut self,
|
&mut self,
|
||||||
option: &dyn SocketOption,
|
option: &dyn SocketOption,
|
||||||
socket: &mut dyn SetSocketLevelOption,
|
socket: &dyn SetSocketLevelOption,
|
||||||
) -> Result<NeedIfacePoll> {
|
) -> Result<NeedIfacePoll> {
|
||||||
match_sock_option_ref!(option, {
|
match_sock_option_ref!(option, {
|
||||||
socket_recv_buf: RecvBuf => {
|
socket_recv_buf: RecvBuf => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user