Fix lints, undo broken set_immediate_interval
This commit is contained in:
@@ -217,17 +217,19 @@ where
|
||||
);
|
||||
|
||||
if delay.is_zero() {
|
||||
unimplemented!("Zero-delay intervals are not yet implemented.")
|
||||
// TODO: vibeshit got this completely wrong
|
||||
// Zero-delay intervals never touch the timer heap or arm an io_uring
|
||||
// timer (a past-deadline kernel timer would fire on every event loop
|
||||
// iteration, spinning the runtime at 100 % CPU). Instead the callback
|
||||
// is stored in `immediate_intervals` and self-schedules as a macrotask
|
||||
// each turn, mirroring JS `setInterval(f, 0)` semantics.
|
||||
let callback = Rc::new(RefCell::new(Box::new(callback) as Box<dyn FnMut()>));
|
||||
current_thread()
|
||||
.immediate_intervals
|
||||
.borrow_mut()
|
||||
.insert(id, Rc::clone(&callback));
|
||||
schedule_immediate_interval(owner, id);
|
||||
// let callback = Rc::new(RefCell::new(Box::new(callback) as Box<dyn FnMut()>));
|
||||
// current_thread()
|
||||
// .immediate_intervals
|
||||
// .borrow_mut()
|
||||
// .insert(id, Rc::clone(&callback));
|
||||
// schedule_immediate_interval(owner, id);
|
||||
} else {
|
||||
let deadline = deadline_from_now(delay);
|
||||
#[cfg(debug_assertions)]
|
||||
@@ -571,6 +573,8 @@ impl Future for YieldNow {
|
||||
}
|
||||
}
|
||||
|
||||
type ImmediateIntervals = RefCell<HashMap<usize, Rc<RefCell<Box<dyn FnMut()>>>>>;
|
||||
|
||||
struct ThreadState {
|
||||
driver: Driver,
|
||||
shared: Arc<ThreadShared>,
|
||||
@@ -580,7 +584,7 @@ struct ThreadState {
|
||||
timers: RefCell<TimerHeap>,
|
||||
/// Zero-delay intervals bypasses the timer heap entirely. Each entry
|
||||
/// re-enqueues itself as a macrotask on every turn.
|
||||
immediate_intervals: RefCell<HashMap<usize, Rc<RefCell<Box<dyn FnMut()>>>>>,
|
||||
immediate_intervals: ImmediateIntervals,
|
||||
next_timer_id: Cell<usize>,
|
||||
children: RefCell<Vec<ChildWorker>>,
|
||||
}
|
||||
@@ -1162,27 +1166,32 @@ fn clear_timer(owner: *const ThreadState, id: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enqueues one macrotask turn for a zero-delay interval.
|
||||
///
|
||||
/// The macrotask checks whether the interval is still live (not cleared), fires
|
||||
/// the callback, and re-enqueues itself for the next turn.
|
||||
fn schedule_immediate_interval(owner: *const ThreadState, id: usize) {
|
||||
push_local_macrotask(Box::new(move || {
|
||||
let callback = current_thread()
|
||||
.immediate_intervals
|
||||
.borrow()
|
||||
.get(&id)
|
||||
.map(Rc::clone);
|
||||
let Some(callback) = callback else {
|
||||
return; // interval was cleared before this turn ran
|
||||
};
|
||||
(callback.borrow_mut())();
|
||||
// Re-enqueue for the next turn if still live.
|
||||
if current_thread().immediate_intervals.borrow().contains_key(&id) {
|
||||
schedule_immediate_interval(owner, id);
|
||||
}
|
||||
}));
|
||||
}
|
||||
// TODO: vibeshit got this completely wrong
|
||||
// /// Enqueues one macrotask turn for a zero-delay interval.
|
||||
// ///
|
||||
// /// The macrotask checks whether the interval is still live (not cleared), fires
|
||||
// /// the callback, and re-enqueues itself for the next turn.
|
||||
// fn schedule_immediate_interval(owner: *const ThreadState, id: usize) {
|
||||
// push_local_macrotask(Box::new(move || {
|
||||
// let callback = current_thread()
|
||||
// .immediate_intervals
|
||||
// .borrow()
|
||||
// .get(&id)
|
||||
// .map(Rc::clone);
|
||||
// let Some(callback) = callback else {
|
||||
// return; // interval was cleared before this turn ran
|
||||
// };
|
||||
// (callback.borrow_mut())();
|
||||
// // Re-enqueue for the next turn if still live.
|
||||
// if current_thread()
|
||||
// .immediate_intervals
|
||||
// .borrow()
|
||||
// .contains_key(&id)
|
||||
// {
|
||||
// schedule_immediate_interval(owner, id);
|
||||
// }
|
||||
// }));
|
||||
// }
|
||||
|
||||
fn dispatch_expired_timers() {
|
||||
let now = deadline_from_now(Duration::ZERO);
|
||||
@@ -1207,12 +1216,8 @@ fn dispatch_expired_timers() {
|
||||
.deadline
|
||||
.checked_add(interval)
|
||||
.unwrap_or(Duration::MAX);
|
||||
let next_timer = TimerNode::interval(
|
||||
timer.id,
|
||||
next_deadline,
|
||||
interval,
|
||||
Rc::clone(&callback),
|
||||
);
|
||||
let next_timer =
|
||||
TimerNode::interval(timer.id, next_deadline, interval, Rc::clone(&callback));
|
||||
current_thread().timers.borrow_mut().insert(next_timer);
|
||||
|
||||
push_local_macrotask(Box::new(move || {
|
||||
@@ -1394,8 +1399,7 @@ mod tests {
|
||||
// turns by awaiting a sleep between checks.
|
||||
let count = Rc::new(Cell::new(0usize));
|
||||
let count_clone = Rc::clone(&count);
|
||||
let handle_slot: Rc<RefCell<Option<super::IntervalHandle>>> =
|
||||
Rc::new(RefCell::new(None));
|
||||
let handle_slot: Rc<RefCell<Option<super::IntervalHandle>>> = Rc::new(RefCell::new(None));
|
||||
let handle_slot_clone = Rc::clone(&handle_slot);
|
||||
|
||||
let handle = set_interval(Duration::ZERO, move || {
|
||||
|
||||
Reference in New Issue
Block a user