autocommit 2022-01-06 19:08:32 CET
This commit is contained in:
parent
cbbc41a463
commit
4a939477a2
51 changed files with 3438 additions and 207 deletions
|
|
@ -1,5 +1,7 @@
|
|||
use crate::pixman::PixmanMemory;
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{compiler_fence, Ordering};
|
||||
use std::{mem, ptr};
|
||||
use thiserror::Error;
|
||||
|
|
@ -19,7 +21,13 @@ pub enum ClientMemError {
|
|||
pub struct ClientMem {
|
||||
failed: Cell<bool>,
|
||||
sigbus_impossible: bool,
|
||||
data: *mut [Cell<u8>],
|
||||
data: *const [Cell<u8>],
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClientMemOffset {
|
||||
mem: Rc<ClientMem>,
|
||||
data: *const [Cell<u8>],
|
||||
}
|
||||
|
||||
impl ClientMem {
|
||||
|
|
@ -53,32 +61,42 @@ impl ClientMem {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { (*self.data).len() }
|
||||
}
|
||||
|
||||
pub fn offset(self: &Rc<Self>, offset: usize) -> ClientMemOffset {
|
||||
let mem = unsafe { &*self.data };
|
||||
ClientMemOffset {
|
||||
mem: self.clone(),
|
||||
data: &mem[offset..],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientMemOffset {
|
||||
pub fn access<T, F: FnOnce(&[Cell<u8>]) -> T>(&self, f: F) -> Result<T, ClientMemError> {
|
||||
unsafe {
|
||||
if self.sigbus_impossible {
|
||||
return Ok(f(&mut *self.data));
|
||||
if self.mem.sigbus_impossible {
|
||||
return Ok(f(&*self.data));
|
||||
}
|
||||
MEM.with(|m| {
|
||||
let mref = MemRef {
|
||||
mem: self,
|
||||
mem: &*self.mem,
|
||||
outer: *m.get(),
|
||||
};
|
||||
*m.get() = &mref;
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
let res = f(&mut *self.data);
|
||||
let res = f(&*self.data);
|
||||
*m.get() = mref.outer;
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
match self.failed.get() {
|
||||
match self.mem.failed.get() {
|
||||
true => Err(ClientMemError::Sigbus),
|
||||
_ => Ok(res),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { (*self.data).len() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ClientMem {
|
||||
|
|
@ -147,3 +165,14 @@ pub fn init() -> Result<(), ClientMemError> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl PixmanMemory for ClientMemOffset {
|
||||
type E = ClientMemError;
|
||||
|
||||
fn access<T, F>(&self, f: F) -> Result<T, Self::E>
|
||||
where
|
||||
F: FnOnce(&[Cell<u8>]) -> T,
|
||||
{
|
||||
ClientMemOffset::access(self, f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue