1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 16:02:59 +01:00

remove some unsafe code

This commit is contained in:
Nikolay Kim 2018-06-19 07:44:01 +06:00
parent 68cd5bdf68
commit 261ad31b9a
10 changed files with 64 additions and 87 deletions

View File

@ -547,7 +547,7 @@ impl<S: 'static, H> ProcessResponse<S, H> {
} }
Ok(Async::Ready(Some(chunk))) => { Ok(Async::Ready(Some(chunk))) => {
self.iostate = IOState::Payload(body); self.iostate = IOState::Payload(body);
match io.write(chunk.into()) { match io.write(&chunk.into()) {
Err(err) => { Err(err) => {
info.error = Some(err.into()); info.error = Some(err.into());
return Ok(FinishingMiddlewares::init( return Ok(FinishingMiddlewares::init(
@ -592,7 +592,7 @@ impl<S: 'static, H> ProcessResponse<S, H> {
break 'inner; break 'inner;
} }
Frame::Chunk(Some(chunk)) => { Frame::Chunk(Some(chunk)) => {
match io.write(chunk) { match io.write(&chunk) {
Err(err) => { Err(err) => {
info.error = Some(err.into()); info.error = Some(err.into());
return Ok( return Ok(

View File

@ -203,7 +203,6 @@ impl<T> Node<T> {
} }
fn insert<I>(&self, next: &Node<I>) { fn insert<I>(&self, next: &Node<I>) {
#[allow(mutable_transmutes)]
unsafe { unsafe {
if let Some(ref next2) = self.next { if let Some(ref next2) = self.next {
let n: &mut Node<()> = let n: &mut Node<()> =

View File

@ -701,8 +701,6 @@ pub(crate) struct TransferEncoding {
kind: TransferEncodingKind, kind: TransferEncodingKind,
} }
unsafe impl Send for TransferEncoding {}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
enum TransferEncodingKind { enum TransferEncodingKind {
/// An Encoder for when Transfer-Encoding includes `chunked`. /// An Encoder for when Transfer-Encoding includes `chunked`.

View File

@ -106,7 +106,7 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
} }
#[inline] #[inline]
fn buffer(&self) -> &mut BytesMut { fn buffer(&mut self) -> &mut BytesMut {
self.buffer.get_mut() self.buffer.get_mut()
} }
@ -181,35 +181,37 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
let mut pos = 0; let mut pos = 0;
let mut has_date = false; let mut has_date = false;
let mut remaining = buffer.remaining_mut(); let mut remaining = buffer.remaining_mut();
let mut buf = unsafe { &mut *(buffer.bytes_mut() as *mut [u8]) }; unsafe {
for (key, value) in msg.headers() { let mut buf = &mut *(buffer.bytes_mut() as *mut [u8]);
if is_bin && key == CONTENT_LENGTH { for (key, value) in msg.headers() {
is_bin = false; if is_bin && key == CONTENT_LENGTH {
continue; is_bin = false;
} continue;
has_date = has_date || key == DATE; }
let v = value.as_ref(); has_date = has_date || key == DATE;
let k = key.as_str().as_bytes(); let v = value.as_ref();
let len = k.len() + v.len() + 4; let k = key.as_str().as_bytes();
if len > remaining { let len = k.len() + v.len() + 4;
unsafe { buffer.advance_mut(pos) }; if len > remaining {
pos = 0; buffer.advance_mut(pos);
buffer.reserve(len); pos = 0;
remaining = buffer.remaining_mut(); buffer.reserve(len);
buf = unsafe { &mut *(buffer.bytes_mut() as *mut _) }; remaining = buffer.remaining_mut();
} buf = &mut *(buffer.bytes_mut() as *mut _);
}
buf[pos..pos + k.len()].copy_from_slice(k); buf[pos..pos + k.len()].copy_from_slice(k);
pos += k.len(); pos += k.len();
buf[pos..pos + 2].copy_from_slice(b": "); buf[pos..pos + 2].copy_from_slice(b": ");
pos += 2; pos += 2;
buf[pos..pos + v.len()].copy_from_slice(v); buf[pos..pos + v.len()].copy_from_slice(v);
pos += v.len(); pos += v.len();
buf[pos..pos + 2].copy_from_slice(b"\r\n"); buf[pos..pos + 2].copy_from_slice(b"\r\n");
pos += 2; pos += 2;
remaining -= len; remaining -= len;
}
buffer.advance_mut(pos);
} }
unsafe { buffer.advance_mut(pos) };
// optimized date header, set_date writes \r\n // optimized date header, set_date writes \r\n
if !has_date { if !has_date {
@ -233,7 +235,7 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
Ok(WriterState::Done) Ok(WriterState::Done)
} }
fn write(&mut self, payload: Binary) -> io::Result<WriterState> { fn write(&mut self, payload: &Binary) -> io::Result<WriterState> {
self.written += payload.len() as u64; self.written += payload.len() as u64;
if !self.flags.contains(Flags::DISCONNECTED) { if !self.flags.contains(Flags::DISCONNECTED) {
if self.flags.contains(Flags::STARTED) { if self.flags.contains(Flags::STARTED) {

View File

@ -77,7 +77,7 @@ impl<H: 'static> Writer for H2Writer<H> {
} }
#[inline] #[inline]
fn buffer(&self) -> &mut BytesMut { fn buffer(&mut self) -> &mut BytesMut {
self.buffer.get_mut() self.buffer.get_mut()
} }
@ -164,7 +164,7 @@ impl<H: 'static> Writer for H2Writer<H> {
} }
} }
fn write(&mut self, payload: Binary) -> io::Result<WriterState> { fn write(&mut self, payload: &Binary) -> io::Result<WriterState> {
self.written = payload.len() as u64; self.written = payload.len() as u64;
if !self.flags.contains(Flags::DISCONNECTED) { if !self.flags.contains(Flags::DISCONNECTED) {

View File

@ -7,7 +7,7 @@ use std::{mem, ptr, slice};
use httprequest::HttpInnerMessage; use httprequest::HttpInnerMessage;
/// Internal use only! unsafe /// Internal use only!
pub(crate) struct SharedMessagePool(RefCell<VecDeque<Rc<HttpInnerMessage>>>); pub(crate) struct SharedMessagePool(RefCell<VecDeque<Rc<HttpInnerMessage>>>);
impl SharedMessagePool { impl SharedMessagePool {
@ -189,14 +189,14 @@ pub fn write_content_length(mut n: usize, bytes: &mut BytesMut) {
} }
pub(crate) fn convert_usize(mut n: usize, bytes: &mut BytesMut) { pub(crate) fn convert_usize(mut n: usize, bytes: &mut BytesMut) {
let mut curr: isize = 39;
let mut buf: [u8; 41] = unsafe { mem::uninitialized() };
buf[39] = b'\r';
buf[40] = b'\n';
let buf_ptr = buf.as_mut_ptr();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
unsafe { unsafe {
let mut curr: isize = 39;
let mut buf: [u8; 41] = mem::uninitialized();
buf[39] = b'\r';
buf[40] = b'\n';
let buf_ptr = buf.as_mut_ptr();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
// eagerly decode 4 characters at a time // eagerly decode 4 characters at a time
while n >= 10_000 { while n >= 10_000 {
let rem = (n % 10_000) as isize; let rem = (n % 10_000) as isize;
@ -229,9 +229,7 @@ pub(crate) fn convert_usize(mut n: usize, bytes: &mut BytesMut) {
curr -= 2; curr -= 2;
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
} }
}
unsafe {
bytes.extend_from_slice(slice::from_raw_parts( bytes.extend_from_slice(slice::from_raw_parts(
buf_ptr.offset(curr), buf_ptr.offset(curr),
41 - curr as usize, 41 - curr as usize,

View File

@ -191,15 +191,14 @@ pub trait Writer {
fn set_date(&self, st: &mut BytesMut); fn set_date(&self, st: &mut BytesMut);
#[doc(hidden)] #[doc(hidden)]
#[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))] fn buffer(&mut self) -> &mut BytesMut;
fn buffer(&self) -> &mut BytesMut;
fn start( fn start(
&mut self, req: &mut HttpInnerMessage, resp: &mut HttpResponse, &mut self, req: &mut HttpInnerMessage, resp: &mut HttpResponse,
encoding: ContentEncoding, encoding: ContentEncoding,
) -> io::Result<WriterState>; ) -> io::Result<WriterState>;
fn write(&mut self, payload: Binary) -> io::Result<WriterState>; fn write(&mut self, payload: &Binary) -> io::Result<WriterState>;
fn write_eof(&mut self) -> io::Result<WriterState>; fn write_eof(&mut self) -> io::Result<WriterState>;

View File

@ -6,58 +6,52 @@ use std::rc::Rc;
use body::Binary; use body::Binary;
/// Internal use only! unsafe
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct SharedBytesPool(RefCell<VecDeque<Rc<BytesMut>>>); pub(crate) struct SharedBytesPool(RefCell<VecDeque<BytesMut>>);
impl SharedBytesPool { impl SharedBytesPool {
pub fn new() -> SharedBytesPool { pub fn new() -> SharedBytesPool {
SharedBytesPool(RefCell::new(VecDeque::with_capacity(128))) SharedBytesPool(RefCell::new(VecDeque::with_capacity(128)))
} }
pub fn get_bytes(&self) -> Rc<BytesMut> { pub fn get_bytes(&self) -> BytesMut {
if let Some(bytes) = self.0.borrow_mut().pop_front() { if let Some(bytes) = self.0.borrow_mut().pop_front() {
bytes bytes
} else { } else {
Rc::new(BytesMut::new()) BytesMut::new()
} }
} }
pub fn release_bytes(&self, mut bytes: Rc<BytesMut>) { pub fn release_bytes(&self, mut bytes: BytesMut) {
let v = &mut self.0.borrow_mut(); let v = &mut self.0.borrow_mut();
if v.len() < 128 { if v.len() < 128 {
Rc::get_mut(&mut bytes).unwrap().clear(); bytes.clear();
v.push_front(bytes); v.push_front(bytes);
} }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct SharedBytes(Option<Rc<BytesMut>>, Option<Rc<SharedBytesPool>>); pub(crate) struct SharedBytes(Option<BytesMut>, Option<Rc<SharedBytesPool>>);
impl Drop for SharedBytes { impl Drop for SharedBytes {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(pool) = self.1.take() { if let Some(pool) = self.1.take() {
if let Some(bytes) = self.0.take() { if let Some(bytes) = self.0.take() {
if Rc::strong_count(&bytes) == 1 { pool.release_bytes(bytes);
pool.release_bytes(bytes);
}
} }
} }
} }
} }
impl SharedBytes { impl SharedBytes {
pub fn new(bytes: Rc<BytesMut>, pool: Rc<SharedBytesPool>) -> SharedBytes { pub fn new(bytes: BytesMut, pool: Rc<SharedBytesPool>) -> SharedBytes {
SharedBytes(Some(bytes), Some(pool)) SharedBytes(Some(bytes), Some(pool))
} }
#[inline(always)] #[inline]
#[allow(mutable_transmutes)] pub(crate) fn get_mut(&mut self) -> &mut BytesMut {
#[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref, inline_always))] self.0.as_mut().unwrap()
pub(crate) fn get_mut(&self) -> &mut BytesMut {
let r: &BytesMut = self.0.as_ref().unwrap().as_ref();
unsafe { &mut *(r as *const _ as *mut _) }
} }
#[inline] #[inline]
@ -75,17 +69,16 @@ impl SharedBytes {
self.0.as_ref().unwrap().as_ref() self.0.as_ref().unwrap().as_ref()
} }
pub fn split_to(&self, n: usize) -> BytesMut { pub fn split_to(&mut self, n: usize) -> BytesMut {
self.get_mut().split_to(n) self.get_mut().split_to(n)
} }
pub fn take(&self) -> BytesMut { pub fn take(&mut self) -> BytesMut {
self.get_mut().take() self.get_mut().take()
} }
#[inline] #[inline]
#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] pub fn extend(&mut self, data: &Binary) {
pub fn extend(&self, data: Binary) {
let buf = self.get_mut(); let buf = self.get_mut();
let data = data.as_ref(); let data = data.as_ref();
buf.reserve(data.len()); buf.reserve(data.len());
@ -93,7 +86,7 @@ impl SharedBytes {
} }
#[inline] #[inline]
pub fn extend_from_slice(&self, data: &[u8]) { pub fn extend_from_slice(&mut self, data: &[u8]) {
let buf = self.get_mut(); let buf = self.get_mut();
buf.reserve(data.len()); buf.reserve(data.len());
SharedBytes::put_slice(buf, data); SharedBytes::put_slice(buf, data);
@ -117,13 +110,7 @@ impl SharedBytes {
impl Default for SharedBytes { impl Default for SharedBytes {
fn default() -> Self { fn default() -> Self {
SharedBytes(Some(Rc::new(BytesMut::new())), None) SharedBytes(Some(BytesMut::new()), None)
}
}
impl Clone for SharedBytes {
fn clone(&self) -> SharedBytes {
SharedBytes(self.0.clone(), self.1.clone())
} }
} }

View File

@ -64,8 +64,6 @@ where
no_signals: bool, no_signals: bool,
} }
unsafe impl<H: IntoHttpHandler + 'static> Send for HttpServer<H> {}
enum ServerCommand { enum ServerCommand {
WorkerDied(usize, Slab<SocketInfo>), WorkerDied(usize, Slab<SocketInfo>),
} }
@ -485,11 +483,9 @@ impl<H: IntoHttpHandler> HttpServer<H> {
self.exit = true; self.exit = true;
self.no_signals = false; self.no_signals = false;
let _ = thread::spawn(move || { let sys = System::new("http-server");
let sys = System::new("http-server"); self.start();
self.start(); sys.run();
sys.run();
}).join();
} }
} }

View File

@ -65,8 +65,6 @@ where
tcp_ka: Option<time::Duration>, tcp_ka: Option<time::Duration>,
} }
unsafe impl<H: HttpHandler + 'static> Send for Worker<H> {}
impl<H: HttpHandler + 'static> Worker<H> { impl<H: HttpHandler + 'static> Worker<H> {
pub(crate) fn new( pub(crate) fn new(
h: Vec<H>, socks: Slab<SocketInfo>, keep_alive: KeepAlive, h: Vec<H>, socks: Slab<SocketInfo>, keep_alive: KeepAlive,