starry_api/imp/task/
exit.rs

1use axprocess::Pid;
2use axsignal::{SignalInfo, Signo};
3use axtask::{TaskExtRef, current};
4use linux_raw_sys::general::SI_KERNEL;
5use starry_core::task::ProcessData;
6
7use crate::{
8    file::FD_TABLE,
9    ptr::UserPtr,
10    signal::{send_signal_process, send_signal_thread},
11};
12
13pub fn do_exit(exit_code: i32, group_exit: bool) -> ! {
14    let curr = current();
15    let curr_ext = curr.task_ext();
16
17    let thread = &curr_ext.thread;
18    info!("{:?} exit with code: {}", thread, exit_code);
19
20    let clear_child_tid = UserPtr::<Pid>::from(curr_ext.thread_data().clear_child_tid());
21    if let Ok(clear_tid) = clear_child_tid.get_as_mut() {
22        *clear_tid = 0;
23
24        let guard = curr_ext
25            .process_data()
26            .futex_table
27            .get(clear_tid as *const _ as usize);
28        if let Some(futex) = guard {
29            futex.notify_one(false);
30        }
31        axtask::yield_now();
32    }
33
34    let process = thread.process();
35    if thread.exit(exit_code) {
36        process.exit();
37        if let Some(parent) = process.parent() {
38            if let Some(signo) = process.data::<ProcessData>().and_then(|it| it.exit_signal) {
39                let _ = send_signal_process(&parent, SignalInfo::new(signo, SI_KERNEL as _));
40            }
41            if let Some(data) = parent.data::<ProcessData>() {
42                data.child_exit_wq.notify_all(false)
43            }
44        }
45
46        process.exit();
47        // TODO: clear namespace resources
48        // FIXME: axns should drop all the resources
49        FD_TABLE.clear();
50    }
51    if group_exit && !process.is_group_exited() {
52        process.group_exit();
53        let sig = SignalInfo::new(Signo::SIGKILL, SI_KERNEL as _);
54        for thr in process.threads() {
55            let _ = send_signal_thread(&thr, sig.clone());
56        }
57    }
58    axtask::exit(exit_code)
59}
60
61pub fn sys_exit(exit_code: i32) -> ! {
62    do_exit(exit_code << 8, false)
63}
64
65pub fn sys_exit_group(exit_code: i32) -> ! {
66    do_exit(exit_code << 8, true)
67}