Add slog integration

This commit is contained in:
Victor Berger 2017-02-22 11:00:03 +01:00
parent 78ba42bdb1
commit a51a780e77
4 changed files with 52 additions and 13 deletions

View File

@ -6,3 +6,8 @@ authors = ["Victor Berger <victor.berger@thalesgroup.com>"]
[dependencies] [dependencies]
wayland-server = "0.8.4" wayland-server = "0.8.4"
nix = "0.7.0" nix = "0.7.0"
slog = { version = "~1.5.2", features = ["max_level_trace", "release_max_level_info"] }
slog-stdlog = "~1.1.0"
[dev-dependencies]
slog-term = "~1.5"

View File

@ -4,4 +4,8 @@
extern crate wayland_server; extern crate wayland_server;
extern crate nix; extern crate nix;
#[macro_use]
extern crate slog;
extern crate slog_stdlog;
pub mod shm; pub mod shm;

View File

@ -68,7 +68,8 @@ mod pool;
/// quickly panic. /// quickly panic.
pub struct ShmGlobal { pub struct ShmGlobal {
formats: Vec<wl_shm::Format>, formats: Vec<wl_shm::Format>,
handler_id: Option<usize> handler_id: Option<usize>,
log: ::slog::Logger
} }
impl ShmGlobal { impl ShmGlobal {
@ -77,13 +78,22 @@ impl ShmGlobal {
/// This global will always advertize `ARGB8888` and `XRGB8888` format /// This global will always advertize `ARGB8888` and `XRGB8888` format
/// as they are required by the protocol. Formats given as argument /// as they are required by the protocol. Formats given as argument
/// as additionnaly advertized. /// as additionnaly advertized.
pub fn new(mut formats: Vec<wl_shm::Format>) -> ShmGlobal { ///
/// An optionnal `slog::Logger` can be provided and will be used as a drain
/// for logging. If `None` is provided, it'll log to `slog-stdlog`.
pub fn new<L>(mut formats: Vec<wl_shm::Format>, logger: L) -> ShmGlobal
where L: Into<Option<::slog::Logger>>
{
use slog::DrainExt;
let log = logger.into().unwrap_or(::slog::Logger::root(::slog_stdlog::StdLog.fuse(), o!()));
// always add the mandatory formats // always add the mandatory formats
formats.push(wl_shm::Format::Argb8888); formats.push(wl_shm::Format::Argb8888);
formats.push(wl_shm::Format::Xrgb8888); formats.push(wl_shm::Format::Xrgb8888);
ShmGlobal { ShmGlobal {
formats: formats, formats: formats,
handler_id: None handler_id: None,
log: log.new(o!("smithay_module" => "shm_handler"))
} }
} }
@ -95,7 +105,7 @@ impl ShmGlobal {
/// This is needed to retrieve the contents of the shm pools and buffers. /// This is needed to retrieve the contents of the shm pools and buffers.
pub fn get_token(&self) -> ShmGlobalToken { pub fn get_token(&self) -> ShmGlobalToken {
ShmGlobalToken { ShmGlobalToken {
hid: self.handler_id.clone().expect("ShmGlobal was not initialized.") hid: self.handler_id.clone().expect("ShmGlobal was not initialized."),
} }
} }
} }
@ -153,7 +163,8 @@ impl Init for ShmGlobal {
fn init(&mut self, evqh: &mut EventLoopHandle, _index: usize) { fn init(&mut self, evqh: &mut EventLoopHandle, _index: usize) {
let id = evqh.add_handler_with_init(ShmHandler { let id = evqh.add_handler_with_init(ShmHandler {
my_id: ::std::usize::MAX, my_id: ::std::usize::MAX,
valid_formats: self.formats.clone() valid_formats: self.formats.clone(),
log: self.log.clone()
}); });
self.handler_id = Some(id); self.handler_id = Some(id);
} }
@ -173,12 +184,14 @@ impl GlobalHandler<wl_shm::WlShm> for ShmGlobal {
struct ShmHandler { struct ShmHandler {
my_id: usize, my_id: usize,
valid_formats: Vec<wl_shm::Format> valid_formats: Vec<wl_shm::Format>,
log: ::slog::Logger
} }
impl Init for ShmHandler { impl Init for ShmHandler {
fn init(&mut self, _evqh: &mut EventLoopHandle, index: usize) { fn init(&mut self, _evqh: &mut EventLoopHandle, index: usize) {
self.my_id = index; self.my_id = index;
debug!(self.log, "Init finished")
} }
} }
@ -189,7 +202,7 @@ impl wl_shm::Handler for ShmHandler {
shm.post_error(wl_shm::Error::InvalidFd as u32, "Invalid size for a new wl_shm_pool.".into()); shm.post_error(wl_shm::Error::InvalidFd as u32, "Invalid size for a new wl_shm_pool.".into());
return return
} }
let mmap_pool = match Pool::new(fd, size as usize) { let mmap_pool = match Pool::new(fd, size as usize, self.log.clone()) {
Ok(p) => p, Ok(p) => p,
Err(()) => { Err(()) => {
shm.post_error(wl_shm::Error::InvalidFd as u32, format!("Failed mmap of fd {}.", fd)); shm.post_error(wl_shm::Error::InvalidFd as u32, format!("Failed mmap of fd {}.", fd));

View File

@ -13,7 +13,9 @@ static SIGBUS_INIT: Once = ONCE_INIT;
static mut OLD_SIGBUS_HANDLER: *mut SigAction = 0 as *mut SigAction; static mut OLD_SIGBUS_HANDLER: *mut SigAction = 0 as *mut SigAction;
pub struct Pool { pub struct Pool {
map: RwLock<MemMap> map: RwLock<MemMap>,
fd: i32,
log: ::slog::Logger
} }
pub enum ResizeError { pub enum ResizeError {
@ -22,19 +24,27 @@ pub enum ResizeError {
} }
impl Pool { impl Pool {
pub fn new(fd: RawFd, size: usize) -> Result<Pool,()> { pub fn new(fd: RawFd, size: usize, log: ::slog::Logger) -> Result<Pool,()> {
let memmap = MemMap::new(fd, size)?; let memmap = MemMap::new(fd, size)?;
trace!(log, "Creating new shm pool"; "fd" => fd as i32, "size" => size);
Ok(Pool { Ok(Pool {
map: RwLock::new(memmap) map: RwLock::new(memmap),
fd: fd as i32,
log: log
}) })
} }
pub fn resize(&self, newsize: i32) -> Result<(),ResizeError> { pub fn resize(&self, newsize: i32) -> Result<(),ResizeError> {
let mut guard = self.map.write().unwrap(); let mut guard = self.map.write().unwrap();
if newsize <= 0 || guard.size() > (newsize as usize) { let oldsize = guard.size();
if newsize <= 0 || oldsize > (newsize as usize) {
return Err(ResizeError::InvalidSize) return Err(ResizeError::InvalidSize)
} }
guard.remap(newsize as usize).map_err(|()| ResizeError::MremapFailed) trace!(self.log, "Resizing shm pool"; "fd" => self.fd as i32, "oldsize" => oldsize, "newsize" => newsize);
guard.remap(newsize as usize).map_err(|()| {
debug!(self.log, "SHM pool resize failed"; "fd" => self.fd as i32, "oldsize" => oldsize, "newsize" => newsize);
ResizeError::MremapFailed
})
} }
pub fn with_data_slice<F: FnOnce(&[u8])>(&self, f: F) -> Result<(),()> { pub fn with_data_slice<F: FnOnce(&[u8])>(&self, f: F) -> Result<(),()> {
@ -45,6 +55,8 @@ impl Pool {
let pool_guard = self.map.read().unwrap(); let pool_guard = self.map.read().unwrap();
trace!(self.log, "Buffer access on shm pool"; "fd" => self.fd as i32);
// Prepare the access // Prepare the access
SIGBUS_GUARD.with(|guard| { SIGBUS_GUARD.with(|guard| {
let (p,_) = guard.get(); let (p,_) = guard.get();
@ -62,7 +74,12 @@ impl Pool {
SIGBUS_GUARD.with(|guard| { SIGBUS_GUARD.with(|guard| {
let (_, triggered) = guard.get(); let (_, triggered) = guard.get();
guard.set((ptr::null_mut(), false)); guard.set((ptr::null_mut(), false));
if triggered { Err(()) } else { Ok(()) } if triggered {
debug!(self.log, "SIGBUS caught on access on shm pool"; "fd" => self.fd);
Err(())
} else {
Ok(())
}
}) })
} }
} }