diff --git a/src/server/settings.rs b/src/server/settings.rs index 59917b87c..c4037b339 100644 --- a/src/server/settings.rs +++ b/src/server/settings.rs @@ -1,11 +1,11 @@ -use bytes::BytesMut; -use futures_cpupool::{Builder, CpuPool}; -use http::StatusCode; use std::cell::{Cell, RefCell, RefMut, UnsafeCell}; use std::fmt::Write; use std::rc::Rc; -use std::sync::Arc; use std::{fmt, mem, net}; + +use bytes::BytesMut; +use futures_cpupool::{Builder, CpuPool}; +use http::StatusCode; use time; use super::channel::Node; @@ -20,54 +20,22 @@ pub struct ServerSettings { addr: Option, secure: bool, host: String, - cpu_pool: Arc, + cpu_pool: UnsafeCell>, responses: Rc>, } -unsafe impl Sync for ServerSettings {} -unsafe impl Send for ServerSettings {} - impl Clone for ServerSettings { fn clone(&self) -> Self { ServerSettings { addr: self.addr, secure: self.secure, host: self.host.clone(), - cpu_pool: self.cpu_pool.clone(), + cpu_pool: UnsafeCell::new(None), responses: HttpResponsePool::pool(), } } } -struct InnerCpuPool { - cpu_pool: UnsafeCell>, -} - -impl fmt::Debug for InnerCpuPool { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "CpuPool") - } -} - -impl InnerCpuPool { - fn new() -> Self { - InnerCpuPool { - cpu_pool: UnsafeCell::new(None), - } - } - fn cpu_pool(&self) -> &CpuPool { - unsafe { - let val = &mut *self.cpu_pool.get(); - if val.is_none() { - *val = Some(Builder::new().create()); - } - val.as_ref().unwrap() - } - } -} - -unsafe impl Sync for InnerCpuPool {} - impl Default for ServerSettings { fn default() -> Self { ServerSettings { @@ -75,7 +43,7 @@ impl Default for ServerSettings { secure: false, host: "localhost:8080".to_owned(), responses: HttpResponsePool::pool(), - cpu_pool: Arc::new(InnerCpuPool::new()), + cpu_pool: UnsafeCell::new(None), } } } @@ -92,7 +60,7 @@ impl ServerSettings { } else { "localhost".to_owned() }; - let cpu_pool = Arc::new(InnerCpuPool::new()); + let cpu_pool = UnsafeCell::new(None); let responses = HttpResponsePool::pool(); ServerSettings { addr, @@ -103,6 +71,21 @@ impl ServerSettings { } } + pub(crate) fn parts(&self) -> (Option, String, bool) { + (self.addr, self.host.clone(), self.secure) + } + + pub(crate) fn from_parts(parts: (Option, String, bool)) -> Self { + let (addr, host, secure) = parts; + ServerSettings { + addr, + host, + secure, + cpu_pool: UnsafeCell::new(None), + responses: HttpResponsePool::pool(), + } + } + /// Returns the socket address of the local half of this TCP connection pub fn local_addr(&self) -> Option { self.addr @@ -120,7 +103,13 @@ impl ServerSettings { /// Returns default `CpuPool` for server pub fn cpu_pool(&self) -> &CpuPool { - self.cpu_pool.cpu_pool() + unsafe { + let val = &mut *self.cpu_pool.get(); + if val.is_none() { + *val = Some(Builder::new().pool_size(2).create()); + } + val.as_ref().unwrap() + } } #[inline] diff --git a/src/server/srv.rs b/src/server/srv.rs index 0e51e2dc3..89f57b891 100644 --- a/src/server/srv.rs +++ b/src/server/srv.rs @@ -351,13 +351,15 @@ where // start workers let mut workers = Vec::new(); for idx in 0..self.threads { - let s = settings.clone(); let (tx, rx) = mpsc::unbounded::>(); let ka = self.keep_alive; let socks = sockets.clone(); let factory = Arc::clone(&self.factory); + let parts = settings.parts(); + let addr = Arbiter::start(move |ctx: &mut Context<_>| { + let s = ServerSettings::from_parts(parts); let apps: Vec<_> = (*factory)() .into_iter() .map(|h| h.into_handler(s.clone())) @@ -642,10 +644,11 @@ impl StreamHandler for HttpServer { let ka = self.keep_alive; let factory = Arc::clone(&self.factory); - let settings = - ServerSettings::new(Some(socks[0].addr), &self.host, false); + let host = self.host.clone(); + let addr = socks[0].addr; let addr = Arbiter::start(move |ctx: &mut Context<_>| { + let settings = ServerSettings::new(Some(addr), &host, false); let apps: Vec<_> = (*factory)() .into_iter() .map(|h| h.into_handler(settings.clone()))