use crate::{TimerError, TimerWheel};
use std::sync::{Arc, Mutex};
pub struct ConcurrentTimerWheel<V> {
inner: Arc<Mutex<TimerWheel<V>>>,
}
impl<V> ConcurrentTimerWheel<V> {
pub fn new(num_slots: usize) -> Self {
Self {
inner: Arc::new(Mutex::new(TimerWheel::new(num_slots))),
}
}
fn locked(&self) -> std::sync::MutexGuard<'_, TimerWheel<V>> {
self.inner.lock().expect("timer-wheel mutex poisoned")
}
pub fn num_slots(&self) -> usize {
self.locked().num_slots()
}
pub fn max_delay(&self) -> u64 {
self.locked().max_delay()
}
pub fn pending(&self) -> usize {
self.locked().pending()
}
pub fn is_empty(&self) -> bool {
self.locked().is_empty()
}
pub fn slot_len(&self, slot: usize) -> usize {
self.locked().slot_len(slot)
}
pub fn schedule(&self, delay_ticks: usize, value: V) -> u64 {
self.locked().schedule(delay_ticks, value)
}
pub fn try_schedule(&self, delay_ticks: usize, value: V) -> Result<u64, TimerError> {
self.locked().try_schedule(delay_ticks, value)
}
pub fn cancel(&self, id: u64) -> bool {
self.locked().cancel(id)
}
pub fn reschedule(&self, id: u64, delay_ticks: usize) -> bool {
self.locked().reschedule(id, delay_ticks)
}
pub fn tick(&self) -> Vec<V> {
self.locked().tick()
}
pub fn advance(&self, ticks: usize) -> Vec<V> {
self.locked().advance(ticks)
}
pub fn drain(&self) -> Vec<V> {
self.locked().drain()
}
pub fn clear(&self) {
self.locked().clear()
}
}
impl<V> Clone for ConcurrentTimerWheel<V> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
#[cfg(test)]
#[path = "concurrent_tests.rs"]
mod tests;