From a51a780e77c39b5741a5e34d4a58e5f3d9cfd911 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Wed, 22 Feb 2017 11:00:03 +0100 Subject: [PATCH] Add slog integration --- Cargo.toml | 5 +++++ src/lib.rs | 4 ++++ src/shm/mod.rs | 27 ++++++++++++++++++++------- src/shm/pool.rs | 29 +++++++++++++++++++++++------ 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 40217c4..47eeab4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,8 @@ authors = ["Victor Berger "] [dependencies] wayland-server = "0.8.4" 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" diff --git a/src/lib.rs b/src/lib.rs index 8ac17eb..3a7d7aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,4 +4,8 @@ extern crate wayland_server; extern crate nix; +#[macro_use] +extern crate slog; +extern crate slog_stdlog; + pub mod shm; diff --git a/src/shm/mod.rs b/src/shm/mod.rs index dd2a956..74be8c6 100644 --- a/src/shm/mod.rs +++ b/src/shm/mod.rs @@ -68,7 +68,8 @@ mod pool; /// quickly panic. pub struct ShmGlobal { formats: Vec, - handler_id: Option + handler_id: Option, + log: ::slog::Logger } impl ShmGlobal { @@ -77,13 +78,22 @@ impl ShmGlobal { /// This global will always advertize `ARGB8888` and `XRGB8888` format /// as they are required by the protocol. Formats given as argument /// as additionnaly advertized. - pub fn new(mut formats: Vec) -> 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(mut formats: Vec, logger: L) -> ShmGlobal + where L: Into> + { + use slog::DrainExt; + let log = logger.into().unwrap_or(::slog::Logger::root(::slog_stdlog::StdLog.fuse(), o!())); + // always add the mandatory formats formats.push(wl_shm::Format::Argb8888); formats.push(wl_shm::Format::Xrgb8888); ShmGlobal { 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. pub fn get_token(&self) -> 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) { let id = evqh.add_handler_with_init(ShmHandler { my_id: ::std::usize::MAX, - valid_formats: self.formats.clone() + valid_formats: self.formats.clone(), + log: self.log.clone() }); self.handler_id = Some(id); } @@ -173,12 +184,14 @@ impl GlobalHandler for ShmGlobal { struct ShmHandler { my_id: usize, - valid_formats: Vec + valid_formats: Vec, + log: ::slog::Logger } impl Init for ShmHandler { fn init(&mut self, _evqh: &mut EventLoopHandle, index: usize) { 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()); 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, Err(()) => { shm.post_error(wl_shm::Error::InvalidFd as u32, format!("Failed mmap of fd {}.", fd)); diff --git a/src/shm/pool.rs b/src/shm/pool.rs index 07dcc21..c2fae05 100644 --- a/src/shm/pool.rs +++ b/src/shm/pool.rs @@ -13,7 +13,9 @@ static SIGBUS_INIT: Once = ONCE_INIT; static mut OLD_SIGBUS_HANDLER: *mut SigAction = 0 as *mut SigAction; pub struct Pool { - map: RwLock + map: RwLock, + fd: i32, + log: ::slog::Logger } pub enum ResizeError { @@ -22,19 +24,27 @@ pub enum ResizeError { } impl Pool { - pub fn new(fd: RawFd, size: usize) -> Result { + pub fn new(fd: RawFd, size: usize, log: ::slog::Logger) -> Result { let memmap = MemMap::new(fd, size)?; + trace!(log, "Creating new shm pool"; "fd" => fd as i32, "size" => size); Ok(Pool { - map: RwLock::new(memmap) + map: RwLock::new(memmap), + fd: fd as i32, + log: log }) } pub fn resize(&self, newsize: i32) -> Result<(),ResizeError> { 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) } - 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(&self, f: F) -> Result<(),()> { @@ -45,6 +55,8 @@ impl Pool { let pool_guard = self.map.read().unwrap(); + trace!(self.log, "Buffer access on shm pool"; "fd" => self.fd as i32); + // Prepare the access SIGBUS_GUARD.with(|guard| { let (p,_) = guard.get(); @@ -62,7 +74,12 @@ impl Pool { SIGBUS_GUARD.with(|guard| { let (_, triggered) = guard.get(); 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(()) + } }) } }