40 lines
1.4 KiB
Rust
40 lines
1.4 KiB
Rust
use crate::{runtime::RuntimeGuard, TaskId, VirtualDom};
|
|
use std::task::Context;
|
|
|
|
impl VirtualDom {
|
|
/// Handle notifications by tasks inside the scheduler
|
|
///
|
|
/// This is precise, meaning we won't poll every task, just tasks that have woken up as notified to use by the
|
|
/// queue
|
|
pub(crate) fn handle_task_wakeup(&mut self, id: TaskId) {
|
|
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
|
let mut tasks = self.runtime.scheduler.tasks.borrow_mut();
|
|
|
|
let task = match tasks.get(id.0) {
|
|
Some(task) => task,
|
|
// The task was removed from the scheduler, so we can just ignore it
|
|
None => return,
|
|
};
|
|
|
|
let mut cx = Context::from_waker(&task.waker);
|
|
|
|
// update the scope stack
|
|
self.runtime.scope_stack.borrow_mut().push(task.scope);
|
|
self.runtime.rendering.set(false);
|
|
|
|
// If the task completes...
|
|
if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
|
|
// Remove it from the scope so we dont try to double drop it when the scope dropes
|
|
let scope = &self.get_scope(task.scope).unwrap();
|
|
scope.context().spawned_tasks.borrow_mut().remove(&id);
|
|
|
|
// Remove it from the scheduler
|
|
tasks.try_remove(id.0);
|
|
}
|
|
|
|
// Remove the scope from the stack
|
|
self.runtime.scope_stack.borrow_mut().pop();
|
|
self.runtime.rendering.set(true);
|
|
}
|
|
}
|