wait.rs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. use crate::{runtime::RuntimeGuard, TaskId, VirtualDom};
  2. use std::task::Context;
  3. impl VirtualDom {
  4. /// Handle notifications by tasks inside the scheduler
  5. ///
  6. /// This is precise, meaning we won't poll every task, just tasks that have woken up as notified to use by the
  7. /// queue
  8. pub(crate) fn handle_task_wakeup(&mut self, id: TaskId) {
  9. let _runtime = RuntimeGuard::new(self.runtime.clone());
  10. let mut tasks = self.runtime.scheduler.tasks.borrow_mut();
  11. let task = match tasks.get(id.0) {
  12. Some(task) => task,
  13. // The task was removed from the scheduler, so we can just ignore it
  14. None => return,
  15. };
  16. let mut cx = Context::from_waker(&task.waker);
  17. // update the scope stack
  18. self.runtime.scope_stack.borrow_mut().push(task.scope);
  19. self.runtime.rendering.set(false);
  20. // If the task completes...
  21. if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
  22. // Remove it from the scope so we dont try to double drop it when the scope dropes
  23. let scope = &self.get_scope(task.scope).unwrap();
  24. scope.context().spawned_tasks.borrow_mut().remove(&id);
  25. // Remove it from the scheduler
  26. tasks.try_remove(id.0);
  27. }
  28. // Remove the scope from the stack
  29. self.runtime.scope_stack.borrow_mut().pop();
  30. self.runtime.rendering.set(true);
  31. }
  32. }