wayland.shm: allow buffer access to return a value

This commit is contained in:
Victor Berger 2018-05-19 19:45:04 +02:00
parent a9ce9a4664
commit 07a98ac5e8
2 changed files with 15 additions and 13 deletions

View File

@ -145,24 +145,26 @@ pub enum BufferAccessError {
/// ///
/// If the buffer is not managed by the provided `ShmGlobal`, the closure is not called /// If the buffer is not managed by the provided `ShmGlobal`, the closure is not called
/// and this method will return `Err(())` (this will be the case for an EGL buffer for example). /// and this method will return `Err(())` (this will be the case for an EGL buffer for example).
pub fn with_buffer_contents<F>(buffer: &Resource<wl_buffer::WlBuffer>, f: F) -> Result<(), BufferAccessError> pub fn with_buffer_contents<F, T>(
buffer: &Resource<wl_buffer::WlBuffer>,
f: F,
) -> Result<T, BufferAccessError>
where where
F: FnOnce(&[u8], BufferData), F: FnOnce(&[u8], BufferData) -> T,
{ {
if !buffer.is_implemented_with::<ShmGlobalData>() { if !buffer.is_implemented_with::<ShmGlobalData>() {
return Err(BufferAccessError::NotManaged); return Err(BufferAccessError::NotManaged);
} }
let data = unsafe { &*(buffer.get_user_data() as *mut InternalBufferData) }; let data = unsafe { &*(buffer.get_user_data() as *mut InternalBufferData) };
if data.pool match data.pool.with_data_slice(|slice| f(slice, data.data)) {
.with_data_slice(|slice| f(slice, data.data)) Ok(t) => Ok(t),
.is_err() Err(()) => {
{ // SIGBUS error occured
// SIGBUS error occured buffer.post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into());
buffer.post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into()); Err(BufferAccessError::BadMap)
return Err(BufferAccessError::BadMap); }
} }
Ok(())
} }
impl Implementation<Resource<wl_shm::WlShm>, wl_shm::Request> for ShmGlobalData { impl Implementation<Resource<wl_shm::WlShm>, wl_shm::Request> for ShmGlobalData {

View File

@ -46,7 +46,7 @@ impl Pool {
}) })
} }
pub fn with_data_slice<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), ()> { pub fn with_data_slice<T, F: FnOnce(&[u8]) -> T>(&self, f: F) -> Result<T, ()> {
// Place the sigbus handler // Place the sigbus handler
SIGBUS_INIT.call_once(|| unsafe { SIGBUS_INIT.call_once(|| unsafe {
place_sigbus_handler(); place_sigbus_handler();
@ -67,7 +67,7 @@ impl Pool {
}); });
let slice = pool_guard.get_slice(); let slice = pool_guard.get_slice();
f(slice); let t = f(slice);
// Cleanup Post-access // Cleanup Post-access
SIGBUS_GUARD.with(|guard| { SIGBUS_GUARD.with(|guard| {
@ -77,7 +77,7 @@ impl Pool {
debug!(self.log, "SIGBUS caught on access on shm pool"; "fd" => self.fd); debug!(self.log, "SIGBUS caught on access on shm pool"; "fd" => self.fd);
Err(()) Err(())
} else { } else {
Ok(()) Ok(t)
} }
}) })
} }