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
/// 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
F: FnOnce(&[u8], BufferData),
F: FnOnce(&[u8], BufferData) -> T,
{
if !buffer.is_implemented_with::<ShmGlobalData>() {
return Err(BufferAccessError::NotManaged);
}
let data = unsafe { &*(buffer.get_user_data() as *mut InternalBufferData) };
if data.pool
.with_data_slice(|slice| f(slice, data.data))
.is_err()
{
// SIGBUS error occured
buffer.post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into());
return Err(BufferAccessError::BadMap);
match data.pool.with_data_slice(|slice| f(slice, data.data)) {
Ok(t) => Ok(t),
Err(()) => {
// SIGBUS error occured
buffer.post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into());
Err(BufferAccessError::BadMap)
}
}
Ok(())
}
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
SIGBUS_INIT.call_once(|| unsafe {
place_sigbus_handler();
@ -67,7 +67,7 @@ impl Pool {
});
let slice = pool_guard.get_slice();
f(slice);
let t = f(slice);
// Cleanup Post-access
SIGBUS_GUARD.with(|guard| {
@ -77,7 +77,7 @@ impl Pool {
debug!(self.log, "SIGBUS caught on access on shm pool"; "fd" => self.fd);
Err(())
} else {
Ok(())
Ok(t)
}
})
}