Files
base64
byteorder
bytes
cfg_if
crossbeam_deque
crossbeam_epoch
crossbeam_queue
crossbeam_utils
fnv
futures
futures_cpupool
httparse
hyper
iovec
language_tags
lazy_static
libc
lock_api
log
maybe_uninit
memoffset
mime
mio
mio_uds
net2
num_cpus
parking_lot
parking_lot_core
percent_encoding
proc_macro2
quote
rand
relay
rfsapi
safemem
scoped_tls
scopeguard
serde
serde_derive
slab
smallvec
syn
take
time
tokio
tokio_codec
tokio_core
tokio_current_thread
tokio_executor
tokio_fs
tokio_io
tokio_proto
tokio_reactor
tokio_service
tokio_sync
tokio_tcp
tokio_threadpool
tokio_timer
tokio_udp
tokio_uds
try_lock
unicase
unicode_xid
want
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::cell::RefCell;
use std::fmt::{self, Write};
use std::str;

use time::{self, Duration};

// "Sun, 06 Nov 1994 08:49:37 GMT".len()
pub const DATE_VALUE_LENGTH: usize = 29;

pub(crate) fn extend(dst: &mut Vec<u8>) {
    CACHED.with(|cache| {
        let mut cache = cache.borrow_mut();
        if !cache.interval {
            cache.update_without_interval();
        }
        dst.extend_from_slice(cache.bytes());
    })
}

pub(crate) fn update_interval() {
    CACHED.with(|cache| {
        let mut cache = cache.borrow_mut();
        cache.interval = true;
        cache.render(time::get_time());
    })
}

pub(crate) fn interval_off() {
    CACHED.with(|cache| {
        let mut cache = cache.borrow_mut();
        cache.interval = false;
    })
}

struct CachedDate {
    bytes: [u8; DATE_VALUE_LENGTH],
    pos: usize,
    next_update: time::Timespec,
    interval: bool,
}

thread_local!(static CACHED: RefCell<CachedDate> = RefCell::new(CachedDate {
    bytes: [0; DATE_VALUE_LENGTH],
    pos: 0,
    next_update: time::Timespec::new(0, 0),
    interval: false,
}));

impl CachedDate {
    fn bytes(&self) -> &[u8] {
        &self.bytes[..]
    }

    fn render(&mut self, now: time::Timespec) {
        self.pos = 0;
        write!(self, "{}", time::at_utc(now).rfc822()).unwrap();
        debug_assert!(self.pos == DATE_VALUE_LENGTH);
    }

    fn update_without_interval(&mut self) {
        let now = time::get_time();
        if now > self.next_update {
            self.render(now);
            self.next_update = now + Duration::seconds(1);
            self.next_update.nsec = 0;
        }
    }
}

impl fmt::Write for CachedDate {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        let len = s.len();
        self.bytes[self.pos..self.pos + len].copy_from_slice(s.as_bytes());
        self.pos += len;
        Ok(())
    }
}

#[test]
fn test_date_len() {
    assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len());
}