Move to hjul crate
Moved timer code into seperate crate (`hjul').
This commit is contained in:
43
Cargo.lock
generated
43
Cargo.lock
generated
@@ -182,11 +182,6 @@ dependencies = [
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ferris"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.6"
|
||||
@@ -249,6 +244,16 @@ name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hjul"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.7.1"
|
||||
@@ -281,6 +286,11 @@ name = "lazy_static"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.60"
|
||||
@@ -353,6 +363,17 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-extras"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-uds"
|
||||
version = "0.6.7"
|
||||
@@ -725,7 +746,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -1033,16 +1054,16 @@ dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ferris 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hjul 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sodiumoxide 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"treebitmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1121,7 +1142,6 @@ dependencies = [
|
||||
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
"checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1"
|
||||
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
|
||||
"checksum ferris 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d5a00f0aaf50c99b8254add9a85fc834a046b82df1c544cd1dc0a404139f84"
|
||||
"checksum filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "450537dc346f0c4d738dda31e790da1da5d4bd12145aad4da0d03d713cb3794f"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
@@ -1131,10 +1151,12 @@ dependencies = [
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8e190892c840661957ba9f32dacfb3eb405e657f9f9f60485605f0bb37d6f8"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
"checksum hjul 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f93f1a4cc3c2ac948c6158e53ba07e9c765c5608d3af5210decafd57cf3d393"
|
||||
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
|
||||
"checksum libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529"
|
||||
"checksum libsodium-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "de29595a79ddae2612ad0f27793a0b86cdf05a12f94ad5b87674540cc568171e"
|
||||
@@ -1142,6 +1164,7 @@ dependencies = [
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
|
||||
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
||||
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
|
||||
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
@@ -1187,7 +1210,7 @@ dependencies = [
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||
"checksum sodiumoxide 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31532969f87f66ea5667b203fdee70aec8ddbe25aac69d243daff58c01688152"
|
||||
"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
|
||||
"checksum spin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbdb51a221842709c2dd65b62ad4b78289fc3e706a02c17a26104528b6aa7837"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
"checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829"
|
||||
|
||||
@@ -22,7 +22,7 @@ futures = "0.1.28"
|
||||
arraydeque = "^0.4"
|
||||
treebitmap = "^0.4"
|
||||
crossbeam-deque = "0.7"
|
||||
ferris = "0.2.0" # consider replacement
|
||||
hjul = "0.1.0"
|
||||
|
||||
[dependencies.x25519-dalek]
|
||||
version = "^0.5"
|
||||
@@ -32,4 +32,4 @@ version = "2.1"
|
||||
features = ["nightly"]
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "0.9.4"
|
||||
proptest = "0.9.4"
|
||||
|
||||
@@ -202,7 +202,10 @@ where
|
||||
rng: &mut R, // rng instance to sample randomness from
|
||||
msg: &[u8], // message buffer
|
||||
src: Option<&'a S>, // optional source endpoint, set when "under load"
|
||||
) -> Result<Output<T>, HandshakeError> where &'a S: Into<&'a SocketAddr> {
|
||||
) -> Result<Output<T>, HandshakeError>
|
||||
where
|
||||
&'a S: Into<&'a SocketAddr>,
|
||||
{
|
||||
match msg.get(0) {
|
||||
Some(&TYPE_INITIATION) => {
|
||||
// parse message
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
mod constants;
|
||||
mod handshake;
|
||||
mod router;
|
||||
mod timers;
|
||||
mod types;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -314,4 +314,7 @@ impl Peer {
|
||||
));
|
||||
res
|
||||
}
|
||||
|
||||
pub fn send(&self, msg : Vec<u8>) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
mod peer;
|
||||
mod timer;
|
||||
|
||||
pub use timer::{Timer, Runner};
|
||||
@@ -1,8 +0,0 @@
|
||||
use super::timer::Timer;
|
||||
|
||||
struct PeerTimers {
|
||||
pub send_keepalive: Timer,
|
||||
pub new_handshake: Timer,
|
||||
pub zero_key_material: Timer,
|
||||
pub persistent_keepalive: Timer,
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
use ferris::*;
|
||||
use spin;
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::u64;
|
||||
|
||||
extern crate test;
|
||||
|
||||
type TimerID = u64;
|
||||
type TimerKey = (u64, usize);
|
||||
type Callback = (Weak<TimerInner>, Box<dyn Fn() -> () + Send + 'static>);
|
||||
|
||||
const ACCURACY: Duration = Duration::from_millis(100);
|
||||
const OFFSET: Duration = Duration::from_millis(1000);
|
||||
|
||||
struct RunnerInner {
|
||||
keys: AtomicU64,
|
||||
wheel: spin::Mutex<CopyWheel<TimerKey>>,
|
||||
running: AtomicBool,
|
||||
callback: spin::Mutex<HashMap<TimerID, Callback>>,
|
||||
}
|
||||
|
||||
struct TimerInner {
|
||||
id: u64,
|
||||
pending: AtomicBool,
|
||||
runner: Weak<RunnerInner>,
|
||||
cnt: AtomicUsize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Timer(Arc<TimerInner>);
|
||||
|
||||
pub struct Runner(Arc<RunnerInner>, Option<thread::JoinHandle<()>>);
|
||||
|
||||
impl Runner {
|
||||
pub fn new() -> Self {
|
||||
let inner = Arc::new(RunnerInner {
|
||||
running: AtomicBool::new(true),
|
||||
callback: spin::Mutex::new(HashMap::new()),
|
||||
keys: AtomicU64::new(0),
|
||||
wheel: spin::Mutex::new(CopyWheel::<TimerKey>::new(vec![
|
||||
Resolution::HundredMs,
|
||||
Resolution::Sec,
|
||||
Resolution::Min,
|
||||
])),
|
||||
});
|
||||
|
||||
// start runner thread
|
||||
let handle = {
|
||||
let inner = inner.clone();
|
||||
thread::spawn(move || {
|
||||
let mut next = Instant::now() + ACCURACY;
|
||||
while inner.running.load(Ordering::Acquire) {
|
||||
// sleep for 1 tick
|
||||
let now = Instant::now();
|
||||
if next > now {
|
||||
thread::sleep(next - now);
|
||||
}
|
||||
next = now + ACCURACY;
|
||||
|
||||
// extract expired events
|
||||
let expired = inner.wheel.lock().expire();
|
||||
|
||||
// handle expired events
|
||||
for key in &expired {
|
||||
let callbacks = inner.callback.lock();
|
||||
let (timer, callback) = callbacks.get(&key.0).unwrap();
|
||||
if let Some(timer) = timer.upgrade() {
|
||||
if timer.pending.swap(false, Ordering::SeqCst) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
Runner(inner, Some(handle))
|
||||
}
|
||||
|
||||
pub fn timer(&self, callback: Box<dyn Fn() -> () + Send + 'static>) -> Timer {
|
||||
let id = self.0.keys.fetch_add(1, Ordering::Relaxed);
|
||||
let inner = Arc::new(TimerInner {
|
||||
id,
|
||||
pending: AtomicBool::new(false),
|
||||
runner: Arc::downgrade(&self.0.clone()),
|
||||
cnt: AtomicUsize::new(0),
|
||||
});
|
||||
|
||||
assert!(id < u64::MAX, "wrapping of ids");
|
||||
|
||||
self.0
|
||||
.callback
|
||||
.lock()
|
||||
.insert(id, (Arc::downgrade(&inner), callback));
|
||||
|
||||
Timer(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
pub fn reset(&self, duration: Duration) {
|
||||
let timer = &self.0;
|
||||
if let Some(runner) = timer.runner.upgrade() {
|
||||
let mut wheel = runner.wheel.lock();
|
||||
let cnt = timer.cnt.fetch_add(1, Ordering::SeqCst);
|
||||
timer.pending.store(true, Ordering::SeqCst);
|
||||
wheel.stop((timer.id, cnt));
|
||||
wheel.start((timer.id, cnt + 1), duration - OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self, duration: Duration) {
|
||||
let timer = &self.0;
|
||||
if timer.pending.load(Ordering::Acquire) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(runner) = timer.runner.upgrade() {
|
||||
let mut wheel = runner.wheel.lock();
|
||||
if !timer.pending.swap(true, Ordering::SeqCst) {
|
||||
let cnt = timer.cnt.fetch_add(1, Ordering::SeqCst);
|
||||
wheel.start((timer.id, cnt + 1), duration - OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
let timer = &self.0;
|
||||
if timer.pending.load(Ordering::Acquire) {
|
||||
if let Some(runner) = timer.runner.upgrade() {
|
||||
let mut wheel = runner.wheel.lock();
|
||||
if timer.pending.swap(false, Ordering::SeqCst) {
|
||||
let cnt = timer.cnt.load(Ordering::SeqCst);
|
||||
wheel.stop((timer.id, cnt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Runner {
|
||||
fn drop(&mut self) {
|
||||
self.0.running.store(false, Ordering::SeqCst);
|
||||
if let Some(handle) = mem::replace(&mut self.1, None) {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_reset(b: &mut Bencher) {
|
||||
let runner = Runner::new();
|
||||
let timer = runner.timer(Box::new(|| {}));
|
||||
b.iter(|| timer.reset(Duration::from_millis(1000)));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_start(b: &mut Bencher) {
|
||||
let runner = Runner::new();
|
||||
let timer = runner.timer(Box::new(|| {}));
|
||||
b.iter(|| timer.start(Duration::from_millis(1000)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user