rust_asio 0.6.0

Asynchronous I/O library
Documentation
use super::TimerContext;
use unsafe_cell::UnsafeBoxedCell;
use core::{Reactor, ThreadIoContext, Expiry, TimerQueue, Operation};

use std::io;
use std::cmp;
use std::time::Duration;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};

pub struct MediocreScheduler {
    mutex: Mutex<TimerQueue>,
    outstanding_work: Arc<AtomicUsize>,
}

impl MediocreScheduler {
    pub fn new(outstanding_work: Arc<AtomicUsize>) -> io::Result<Self> {
        Ok(MediocreScheduler{
            mutex: Default::default(),
            outstanding_work: outstanding_work,
        })
    }

    pub fn startup(&self, _: &Reactor) {
    }

    pub fn cleanup(&self, _: &Reactor) {
    }

    pub fn wait_duration(&self, max: Duration) -> Duration {
        if let Some(expiry) = self.mutex.lock().unwrap().front() {
            cmp::min(max, expiry.left())
        } else {
            max
        }
    }

    pub fn timer_queue_insert(&self, mut timer: UnsafeBoxedCell<TimerContext>, op: Operation) -> Option<Operation> {
        let (old_op, update) = {
            let mut tq = self.mutex.lock().unwrap();
            let old_op = timer.op.take();
            timer.op = Some(op);
            (old_op, tq.insert(&timer).is_some())
        };

        if update {
            timer.ctx.0.interrupter.interrupt();
        }

        if old_op.is_none() {
            self.outstanding_work.fetch_add(1, Ordering::SeqCst);
        }
        old_op
    }

    pub fn timer_queue_remove(&self, mut timer: UnsafeBoxedCell<TimerContext>) -> Option<Operation> {
        let mut tq = self.mutex.lock().unwrap();
        let old_op = timer.op.take();
        let _ = tq.erase(&timer);
        if old_op.is_some() {
            self.outstanding_work.fetch_sub(1, Ordering::SeqCst);
        }
        old_op
    }

    pub fn cancel_all_timers(&self, this: &mut ThreadIoContext) {
        self.mutex.lock().unwrap().cancel_all_timers(this)
    }

    pub fn get_ready_timers(&self, this: &mut ThreadIoContext) {
        let len = this.len();
        self.mutex.lock().unwrap().get_ready_timers(this, Expiry::now());
        self.outstanding_work.fetch_sub(this.len() - len, Ordering::SeqCst);
    }
}