1
0
Fork 0
forked from wry/wry

autocommit 2022-01-06 19:08:32 CET

This commit is contained in:
Julian Orth 2022-01-06 19:08:32 +01:00
parent cbbc41a463
commit 4a939477a2
51 changed files with 3438 additions and 207 deletions

View file

@ -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)
}
}