From ee23e4def16a5643a0dff83358eaf189801dac53 Mon Sep 17 00:00:00 2001 From: WuZheng Date: Thu, 14 Nov 2024 17:19:21 +0800 Subject: [PATCH] fix bugs for pipe's write end closure and exit group --- api/ruxos_posix_api/src/imp/pipe.rs | 12 +++++++++--- api/ruxos_posix_api/src/imp/pthread/mod.rs | 9 ++++++--- api/ruxos_posix_api/src/imp/task.rs | 3 +-- modules/ruxtask/src/fs.rs | 10 ++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/api/ruxos_posix_api/src/imp/pipe.rs b/api/ruxos_posix_api/src/imp/pipe.rs index 8b61a3f1..6fb29a04 100644 --- a/api/ruxos_posix_api/src/imp/pipe.rs +++ b/api/ruxos_posix_api/src/imp/pipe.rs @@ -7,7 +7,7 @@ * See the Mulan PSL v2 for more details. */ -use alloc::sync::Arc; +use alloc::sync::{Weak, Arc}; use core::ffi::c_int; use axerrno::{LinuxError, LinuxResult}; @@ -87,6 +87,8 @@ impl PipeRingBuffer { pub struct Pipe { readable: bool, buffer: Arc>, + // to find the write end when the read end is closed + _write_end_closed: Option>>, } impl Pipe { @@ -95,10 +97,12 @@ impl Pipe { let read_end = Pipe { readable: true, buffer: buffer.clone(), + _write_end_closed: None, }; let write_end = Pipe { readable: false, - buffer, + buffer: buffer.clone(), + _write_end_closed: Some(Arc::downgrade(&buffer)), }; (read_end, write_end) } @@ -112,7 +116,9 @@ impl Pipe { } pub fn write_end_close(&self) -> bool { - Arc::strong_count(&self.buffer) == 1 + let write_end_count = Arc::weak_count(&self.buffer); + // error!("Pipe::write_end_close <= buffer: {:#?} {:#?}", write_end_count, Arc::as_ptr(&self.buffer)); + write_end_count == 0 } } diff --git a/api/ruxos_posix_api/src/imp/pthread/mod.rs b/api/ruxos_posix_api/src/imp/pthread/mod.rs index 759512cf..405d5b13 100644 --- a/api/ruxos_posix_api/src/imp/pthread/mod.rs +++ b/api/ruxos_posix_api/src/imp/pthread/mod.rs @@ -12,7 +12,7 @@ use core::cell::UnsafeCell; use core::ffi::{c_int, c_void}; use axerrno::{LinuxError, LinuxResult}; -use ruxtask::AxTaskRef; +use ruxtask::{current, AxTaskRef}; use spin::RwLock; use crate::ctypes; @@ -228,9 +228,12 @@ pub fn sys_pthread_exit(retval: *mut c_void) -> ! { /// Exits the current thread. The value `retval` will be returned to the joiner. pub fn sys_exit_group(status: c_int) -> ! { - error!("sys_exit_group <= {:#?}", status); + debug!("sys_exit_group <= status: {:#?}", status); // TODO: exit all threads, send signal to all threads + + // drop all file opened by current task + current().fs.lock().as_mut().unwrap().close_all_files(); #[cfg(feature = "multitask")] ruxtask::exit(status); @@ -322,7 +325,7 @@ pub unsafe fn sys_clone( TID_TO_PTHREAD.write().insert(tid, ForceSendSync(ptr)); 0 }; - warn!("will sys_clone <= pid: {}", pid); + debug!("will sys_clone <= pid: {}", pid); return Ok(pid); } else { debug!("ONLY support CLONE_THREAD and SIGCHLD"); diff --git a/api/ruxos_posix_api/src/imp/task.rs b/api/ruxos_posix_api/src/imp/task.rs index b4227b8a..17d365c8 100644 --- a/api/ruxos_posix_api/src/imp/task.rs +++ b/api/ruxos_posix_api/src/imp/task.rs @@ -54,7 +54,7 @@ pub fn sys_getppid() -> c_int { /// Wait for a child process to exit and return its status. /// -/// TOSO, wstatus, options, and rusage are not implemented yet. +/// TODO: part of options, and rusage are not implemented yet. pub fn sys_wait4( pid: c_int, wstatus: *mut c_int, @@ -104,7 +104,6 @@ pub fn sys_wait4( if parent_pid == ruxtask::current().id().as_u64() { if task.state() == ruxtask::task::TaskState::Exited { // add to to_remove list - let task_ref = process_map.get(child_pid).unwrap(); unsafe { // lower 8 bits of exit_code is the signal number, while upper 8 bits of exit_code is the exit status // according to "bits/waitstatus.h" in glibc source code. diff --git a/modules/ruxtask/src/fs.rs b/modules/ruxtask/src/fs.rs index 75d71a33..b603d237 100644 --- a/modules/ruxtask/src/fs.rs +++ b/modules/ruxtask/src/fs.rs @@ -216,6 +216,16 @@ pub struct FileSystem { pub root_dir: Arc, } +impl FileSystem { + pub fn close_all_files(&mut self) { + for fd in 0..self.fd_table.capacity() { + if let Some(_) = self.fd_table.get(fd) { + self.fd_table.remove(fd).unwrap(); + } + } + } +} + impl Clone for FileSystem { fn clone(&self) -> Self { let mut new_fd_table = FlattenObjects::new();