Can I create my own pointer to a stack object?
No, but you can just move the stack object to your scheduler. Your scheduler will increase in size with every closure you plan, but it will be completely autonomous, even moveable.
The basic idea is that your planner becomes a kind of singly linked list:
pub trait Scheduler: Sized { fn run(self); } pub struct NoHeapScheduler<F: FnOnce(), T: Scheduler> { inner: T, f: F, } impl<F: FnOnce(), T: Scheduler> Scheduler for NoHeapScheduler<F, T> { fn run(self) { self.inner.run(); (self.f)() } }
The Scheduler
attribute is here to break the recursion chain in NoHeapScheduler
(otherwise we need a function like varadic generics).
To complete the chain, we also implement a Scheduler
for some type of no-op, for example. ()
:
impl Scheduler for () { fn run(self) {} }
Now it remains only to add new locks.
impl<F: FnOnce(), T: Scheduler> NoHeapScheduler<F, T> { fn add_task<F2: FnOnce()>(self, f: F2) -> NoHeapScheduler<F2, Self> { NoHeapScheduler { inner: self, f: f, } } }
This method moves the current scheduler to the new scheduler and adds a scheduled close.
You can use this function as follows:
let scheduler = scheduler.add_task(task);
A fully working example on a playground