Drop the strong reference of Task before exiting

This commit is contained in:
jellllly420
2024-10-27 15:00:59 +08:00
committed by Tate, Hongliang Tian
parent f8bd71a1e7
commit cff688e128
2 changed files with 9 additions and 3 deletions

View File

@ -149,7 +149,7 @@ impl TaskOptions {
pub fn build(self) -> Result<Task> { pub fn build(self) -> Result<Task> {
/// all task will entering this function /// all task will entering this function
/// this function is mean to executing the task_fn in Task /// this function is mean to executing the task_fn in Task
extern "C" fn kernel_task_entry() { extern "C" fn kernel_task_entry() -> ! {
let current_task = current_task() let current_task = current_task()
.expect("no current task, it should have current task in kernel task entry"); .expect("no current task, it should have current task in kernel task entry");
// SAFETY: The scheduler will ensure that the task is only accessed // SAFETY: The scheduler will ensure that the task is only accessed
@ -159,6 +159,10 @@ impl TaskOptions {
.take() .take()
.expect("task function is `None` when trying to run"); .expect("task function is `None` when trying to run");
task_func(); task_func();
// Manually drop all the on-stack variables to prevent memory leakage!
// This is needed because `scheduler::exit_current()` will never return.
drop(current_task);
scheduler::exit_current(); scheduler::exit_current();
} }

View File

@ -183,7 +183,7 @@ pub(super) fn run_new_task(runnable: Arc<Task>) {
/// Dequeues the current task from its runqueue. /// Dequeues the current task from its runqueue.
/// ///
/// This should only be called if the current is to exit. /// This should only be called if the current is to exit.
pub(super) fn exit_current() { pub(super) fn exit_current() -> ! {
reschedule(&mut |local_rq: &mut dyn LocalRunQueue| { reschedule(&mut |local_rq: &mut dyn LocalRunQueue| {
let _ = local_rq.dequeue_current(); let _ = local_rq.dequeue_current();
if let Some(next_task) = local_rq.pick_next_current() { if let Some(next_task) = local_rq.pick_next_current() {
@ -191,7 +191,9 @@ pub(super) fn exit_current() {
} else { } else {
ReschedAction::Retry ReschedAction::Retry
} }
}) });
unreachable!()
} }
/// Yields execution. /// Yields execution.