diff --git a/os/src/kernel/syscall/io.rs b/os/src/kernel/syscall/io.rs index 43853faf..42bda890 100644 --- a/os/src/kernel/syscall/io.rs +++ b/os/src/kernel/syscall/io.rs @@ -84,6 +84,20 @@ fn wait_for_would_block(file: Arc, task: crate::kernel::SharedTask) -> Ok(()) } +fn file_read_ready(file: &Arc) -> bool { + if let Some(pipe_file) = file.as_any().downcast_ref::() { + return pipe_file.read_ready(); + } + file.readable() +} + +fn file_write_ready(file: &Arc) -> bool { + if let Some(pipe_file) = file.as_any().downcast_ref::() { + return pipe_file.write_ready(); + } + file.writable() +} + /// 向文件描述符写入数据 pub fn write(fd: usize, buf: *const u8, count: usize) -> isize { loop { @@ -671,11 +685,11 @@ fn poll_with_timeout( } }; - if (pollfd.events & POLLIN) != 0 && file.readable() { + if (pollfd.events & POLLIN) != 0 && file_read_ready(&file) { pollfd.revents |= POLLIN; } - if (pollfd.events & POLLOUT) != 0 && file.writable() { + if (pollfd.events & POLLOUT) != 0 && file_write_ready(&file) { pollfd.revents |= POLLOUT; } @@ -889,14 +903,14 @@ fn select_common( let mut fd_ready = false; if check_read - && file.readable() + && file_read_ready(&file) && let Some(ref mut set) = read_set { set.set(fd); fd_ready = true; } if check_write - && file.writable() + && file_write_ready(&file) && let Some(ref mut set) = write_set { set.set(fd); diff --git a/os/src/kernel/syscall/network/connection_ops.rs b/os/src/kernel/syscall/network/connection_ops.rs index 6b203654..24654344 100644 --- a/os/src/kernel/syscall/network/connection_ops.rs +++ b/os/src/kernel/syscall/network/connection_ops.rs @@ -255,7 +255,12 @@ pub fn send(sockfd: i32, buf: *const u8, len: usize, _flags: i32) -> isize { return n as isize; } Err(e) => { - pr_debug!("send: sockfd={}, len={} -> error={:?}", sockfd, chunk_len, e); + pr_debug!( + "send: sockfd={}, len={} -> error={:?}", + sockfd, + chunk_len, + e + ); if e == crate::vfs::FsError::WouldBlock { if let Some(socket_file) = file.as_any().downcast_ref::() && !socket_file.flags().contains(OpenFlags::O_NONBLOCK) @@ -325,11 +330,21 @@ pub fn recv(sockfd: i32, buf: *mut u8, len: usize, _flags: i32) -> isize { match result { Ok(n) => { - pr_debug!("recv: sockfd={}, len={} -> received={}", sockfd, chunk_len, n); + pr_debug!( + "recv: sockfd={}, len={} -> received={}", + sockfd, + chunk_len, + n + ); return n as isize; } Err(e) => { - pr_debug!("recv: sockfd={}, len={} -> error={:?}", sockfd, chunk_len, e); + pr_debug!( + "recv: sockfd={}, len={} -> error={:?}", + sockfd, + chunk_len, + e + ); if e == crate::vfs::FsError::WouldBlock { if let Some(socket_file) = file.as_any().downcast_ref::() && !socket_file.flags().contains(OpenFlags::O_NONBLOCK) diff --git a/os/src/kernel/syscall/network/socket_ops.rs b/os/src/kernel/syscall/network/socket_ops.rs index a5371700..07c26ac7 100644 --- a/os/src/kernel/syscall/network/socket_ops.rs +++ b/os/src/kernel/syscall/network/socket_ops.rs @@ -499,12 +499,20 @@ fn replenish_tcp_listeners( while network_stack().tcp_spare_listener_count(socket_file, listen_endpoint) < target { let new_listen_handle = match create_tcp_socket() { Ok(SocketHandle::Tcp(h)) => h, - Err(e) => return Err(e.to_errno()), + Err(e) => { + if network_stack().tcp_spare_listener_count(socket_file, listen_endpoint) > 0 { + break; + } + return Err(e.to_errno()); + } Ok(SocketHandle::Udp(_)) => return Err(-(crate::uapi::errno::EINVAL as isize)), }; if let Err(e) = network_stack().tcp_listen(new_listen_handle, listen_endpoint) { network_stack().remove_tcp_socket(new_listen_handle); + if network_stack().tcp_spare_listener_count(socket_file, listen_endpoint) > 0 { + break; + } return Err(e.to_errno()); } diff --git a/os/src/net/socket.rs b/os/src/net/socket.rs index 81577ce6..5a6ba2ad 100644 --- a/os/src/net/socket.rs +++ b/os/src/net/socket.rs @@ -169,7 +169,9 @@ impl SocketFile { pub(crate) fn udp_push(&self, d: UdpDatagram) -> bool { let mut q = self.udp_rx_queue.lock(); - if q.len() == q.capacity() { + if q.len() >= UDP_RXQ_MAX_CAP { + let _ = q.pop_front(); + } else if q.len() == q.capacity() { let old_capacity = q.capacity(); if old_capacity < UDP_RXQ_MAX_CAP { let new_capacity = old_capacity diff --git a/os/src/vfs/impls/pipe_file.rs b/os/src/vfs/impls/pipe_file.rs index 2c5b0b13..55271cd6 100644 --- a/os/src/vfs/impls/pipe_file.rs +++ b/os/src/vfs/impls/pipe_file.rs @@ -276,18 +276,23 @@ impl PipeFile { buffer.set_capacity(new_size)?; Ok(buffer.get_capacity()) } + + pub fn read_ready(&self) -> bool { + self.end_type.readable() && self.buffer.lock().can_read_now() + } + + pub fn write_ready(&self) -> bool { + self.end_type.writable() && self.buffer.lock().can_write_now() + } } impl File for PipeFile { fn readable(&self) -> bool { - self.end_type.readable() && self.buffer.lock().can_read_now() + self.end_type.readable() } fn writable(&self) -> bool { - if !self.end_type.writable() { - return false; - } - self.buffer.lock().can_write_now() + self.end_type.writable() } fn read(&self, buf: &mut [u8]) -> Result {