fix: use arcwake instead of rcwake
This commit is contained in:
1 parent
651ab3e7e3
commit
2fa3fe1fc0
16 files changed
+326
-79
No files matched your search
@@ -8,7 +8,7 @@ mod waker;
|
||||
|
||||
pub use suspense::*;
|
||||
pub use task::*;
|
||||
pub use waker::RcWake;
|
||||
pub use waker::ArcWake;
|
||||
|
||||
/// The type of message that can be sent to the scheduler.
|
||||
///
|
||||
@@ -25,16 +25,16 @@ pub(crate) enum SchedulerMsg {
|
||||
SuspenseNotified(SuspenseId),
|
||||
}
|
||||
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||
|
||||
pub(crate) struct Scheduler {
|
||||
pub sender: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
|
||||
|
||||
/// Tasks created with cx.spawn
|
||||
pub tasks: RefCell<Slab<Rc<LocalTask>>>,
|
||||
pub tasks: RefCell<Slab<Arc<LocalTask>>>,
|
||||
|
||||
/// Async components
|
||||
pub leaves: RefCell<Slab<Rc<SuspenseLeaf>>>,
|
||||
pub leaves: RefCell<Slab<Arc<SuspenseLeaf>>>,
|
||||
}
|
||||
|
||||
impl Scheduler {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use super::{waker::RcWake, SchedulerMsg};
|
||||
use super::{waker::ArcWake, SchedulerMsg};
|
||||
use crate::ElementId;
|
||||
use crate::{innerlude::Mutations, Element, ScopeId};
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
collections::HashSet,
|
||||
@@ -42,8 +43,8 @@ pub(crate) struct SuspenseLeaf {
|
||||
pub(crate) task: *mut dyn Future<Output = Element<'static>>,
|
||||
}
|
||||
|
||||
impl RcWake for SuspenseLeaf {
|
||||
fn wake_by_ref(arc_self: &Rc<Self>) {
|
||||
impl ArcWake for SuspenseLeaf {
|
||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
||||
arc_self.notified.set(true);
|
||||
_ = arc_self
|
||||
.tx
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use super::{waker::RcWake, Scheduler, SchedulerMsg};
|
||||
use super::{waker::ArcWake, Scheduler, SchedulerMsg};
|
||||
use crate::ScopeId;
|
||||
use std::cell::RefCell;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::{pin::Pin, rc::Rc};
|
||||
|
||||
/// A task's unique identifier.
|
||||
@@ -35,7 +36,7 @@ impl Scheduler {
|
||||
let entry = tasks.vacant_entry();
|
||||
let task_id = TaskId(entry.key());
|
||||
|
||||
entry.insert(Rc::new(LocalTask {
|
||||
entry.insert(Arc::new(LocalTask {
|
||||
id: task_id,
|
||||
tx: self.sender.clone(),
|
||||
task: RefCell::new(Box::pin(task)),
|
||||
@@ -57,8 +58,8 @@ impl Scheduler {
|
||||
}
|
||||
}
|
||||
|
||||
impl RcWake for LocalTask {
|
||||
fn wake_by_ref(arc_self: &Rc<Self>) {
|
||||
impl ArcWake for LocalTask {
|
||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
||||
_ = arc_self
|
||||
.tx
|
||||
.unbounded_send(SchedulerMsg::TaskNotified(arc_self.id));
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
ScopeId, TaskId, VNode, VirtualDom,
|
||||
};
|
||||
|
||||
use super::{waker::RcWake, SuspenseId};
|
||||
use super::{waker::ArcWake, SuspenseId};
|
||||
|
||||
impl VirtualDom {
|
||||
/// Handle notifications by tasks inside the scheduler
|
||||
@@ -67,18 +67,21 @@ impl VirtualDom {
|
||||
// we should attach them to that component and then render its children
|
||||
// continue rendering the tree until we hit yet another suspended component
|
||||
if let Poll::Ready(new_nodes) = as_pinned_mut.poll_unpin(&mut cx) {
|
||||
// safety: we're not going to modify the suspense context but we don't want to make a clone of it
|
||||
let fiber = self.acquire_suspense_boundary(leaf.scope_id);
|
||||
|
||||
let scope = &mut self.scopes[scope_id.0];
|
||||
let arena = scope.current_frame();
|
||||
|
||||
let ret = arena.bump.alloc(RenderReturn::Sync(new_nodes));
|
||||
let ret = arena.bump.alloc(match new_nodes {
|
||||
Some(new) => RenderReturn::Ready(new),
|
||||
None => RenderReturn::default(),
|
||||
});
|
||||
|
||||
arena.node.set(ret);
|
||||
|
||||
fiber.waiting_on.borrow_mut().remove(&id);
|
||||
|
||||
if let RenderReturn::Sync(Some(template)) = ret {
|
||||
if let RenderReturn::Ready(template) = ret {
|
||||
let mutations_ref = &mut fiber.mutations.borrow_mut();
|
||||
let mutations = &mut **mutations_ref;
|
||||
let template: &VNode = unsafe { std::mem::transmute(template) };
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use std::task::{RawWaker, RawWakerVTable, Waker};
|
||||
use std::{mem, rc::Rc};
|
||||
|
||||
pub trait RcWake: Sized {
|
||||
pub trait ArcWake: Sized {
|
||||
/// Create a waker from this self-wakening object
|
||||
fn waker(self: &Rc<Self>) -> Waker {
|
||||
unsafe fn rc_vtable<T: RcWake>() -> &'static RawWakerVTable {
|
||||
fn waker(self: &Arc<Self>) -> Waker {
|
||||
unsafe fn rc_vtable<T: ArcWake>() -> &'static RawWakerVTable {
|
||||
&RawWakerVTable::new(
|
||||
|data| {
|
||||
let arc = mem::ManuallyDrop::new(Rc::<T>::from_raw(data.cast::<T>()));
|
||||
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
|
||||
let _rc_clone: mem::ManuallyDrop<_> = arc.clone();
|
||||
RawWaker::new(data, rc_vtable::<T>())
|
||||
},
|
||||
|data| Rc::from_raw(data.cast::<T>()).wake(),
|
||||
|data| Arc::from_raw(data.cast::<T>()).wake(),
|
||||
|data| {
|
||||
let arc = mem::ManuallyDrop::new(Rc::<T>::from_raw(data.cast::<T>()));
|
||||
RcWake::wake_by_ref(&arc);
|
||||
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
|
||||
ArcWake::wake_by_ref(&arc);
|
||||
},
|
||||
|data| drop(Rc::<T>::from_raw(data.cast::<T>())),
|
||||
|data| drop(Arc::<T>::from_raw(data.cast::<T>())),
|
||||
)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
Waker::from_raw(RawWaker::new(
|
||||
Rc::into_raw(self.clone()).cast(),
|
||||
Arc::into_raw(self.clone()).cast(),
|
||||
rc_vtable::<Self>(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn wake_by_ref(arc_self: &Rc<Self>);
|
||||
fn wake_by_ref(arc_self: &Arc<Self>);
|
||||
|
||||
fn wake(self: Rc<Self>) {
|
||||
fn wake(self: Arc<Self>) {
|
||||
Self::wake_by_ref(&self)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user