1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-23 10:01:06 +00:00

refactor date rendering

This commit is contained in:
Nikolay Kim 2018-10-08 10:16:19 -07:00
parent cfad5bf1f3
commit 03d988b898

View file

@ -1,4 +1,4 @@
use std::cell::{RefCell, RefMut, UnsafeCell}; use std::cell::{Cell, RefCell, RefMut};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::Write; use std::fmt::Write;
use std::rc::Rc; use std::rc::Rc;
@ -139,7 +139,7 @@ struct Inner<H> {
bytes: Rc<SharedBytesPool>, bytes: Rc<SharedBytesPool>,
messages: &'static RequestPool, messages: &'static RequestPool,
node: RefCell<Node<()>>, node: RefCell<Node<()>>,
date: UnsafeCell<(bool, Date)>, date: Cell<Option<Date>>,
} }
impl<H> Clone for ServiceConfig<H> { impl<H> Clone for ServiceConfig<H> {
@ -174,7 +174,7 @@ impl<H> ServiceConfig<H> {
bytes: Rc::new(SharedBytesPool::new()), bytes: Rc::new(SharedBytesPool::new()),
messages: RequestPool::pool(settings), messages: RequestPool::pool(settings),
node: RefCell::new(Node::head()), node: RefCell::new(Node::head()),
date: UnsafeCell::new((false, Date::new())), date: Cell::new(None),
})) }))
} }
@ -214,11 +214,6 @@ impl<H> ServiceConfig<H> {
pub(crate) fn get_request(&self) -> Request { pub(crate) fn get_request(&self) -> Request {
RequestPool::get(self.0.messages) RequestPool::get(self.0.messages)
} }
fn update_date(&self) {
// Unsafe: WorkerSetting is !Sync and !Send
unsafe { (*self.0.date.get()).0 = false };
}
} }
impl<H: 'static> ServiceConfig<H> { impl<H: 'static> ServiceConfig<H> {
@ -272,51 +267,39 @@ impl<H: 'static> ServiceConfig<H> {
} }
} }
pub(crate) fn set_date(&self, dst: &mut BytesMut, full: bool) { fn check_date(&self) {
// Unsafe: WorkerSetting is !Sync and !Send if unsafe { &*self.0.date.as_ptr() }.is_none() {
let date_bytes = unsafe { self.0.date.set(Some(Date::new()));
let date = &mut (*self.0.date.get());
if !date.0 {
date.1.update();
date.0 = true;
// periodic date update // periodic date update
let s = self.clone(); let s = self.clone();
spawn(sleep(Duration::from_millis(500)).then(move |_| { spawn(sleep(Duration::from_millis(500)).then(move |_| {
s.update_date(); s.0.date.set(None);
future::ok(()) future::ok(())
})); }));
} }
&date.1.bytes }
};
pub(crate) fn set_date(&self, dst: &mut BytesMut, full: bool) {
self.check_date();
let date = &unsafe { &*self.0.date.as_ptr() }.as_ref().unwrap().bytes;
if full { if full {
let mut buf: [u8; 39] = [0; 39]; let mut buf: [u8; 39] = [0; 39];
buf[..6].copy_from_slice(b"date: "); buf[..6].copy_from_slice(b"date: ");
buf[6..35].copy_from_slice(date_bytes); buf[6..35].copy_from_slice(date);
buf[35..].copy_from_slice(b"\r\n\r\n"); buf[35..].copy_from_slice(b"\r\n\r\n");
dst.extend_from_slice(&buf); dst.extend_from_slice(&buf);
} else { } else {
dst.extend_from_slice(date_bytes); dst.extend_from_slice(date);
} }
} }
#[inline] #[inline]
pub(crate) fn now(&self) -> Instant { pub(crate) fn now(&self) -> Instant {
unsafe { self.check_date();
let date = &mut (*self.0.date.get()); unsafe { &*self.0.date.as_ptr() }.as_ref().unwrap().current
if !date.0 {
date.1.update();
date.0 = true;
// periodic date update
let s = self.clone();
spawn(sleep(Duration::from_millis(500)).then(move |_| {
s.update_date();
future::ok(())
}));
}
date.1.current
}
} }
} }
@ -435,6 +418,7 @@ impl<H> ServiceConfigBuilder<H> {
} }
} }
#[derive(Copy, Clone)]
struct Date { struct Date {
current: Instant, current: Instant,
bytes: [u8; DATE_VALUE_LENGTH], bytes: [u8; DATE_VALUE_LENGTH],