shm: close client buffers in the cpu worker
This commit is contained in:
parent
d40e605f66
commit
ece56d91d3
7 changed files with 79 additions and 16 deletions
|
|
@ -353,9 +353,10 @@ impl Input {
|
||||||
async fn handle_keymap(&self, input: JayInputId) -> Vec<u8> {
|
async fn handle_keymap(&self, input: JayInputId) -> Vec<u8> {
|
||||||
let data = Rc::new(RefCell::new(Vec::new()));
|
let data = Rc::new(RefCell::new(Vec::new()));
|
||||||
jay_input::Keymap::handle(&self.tc, input, data.clone(), |d, map| {
|
jay_input::Keymap::handle(&self.tc, input, data.clone(), |d, map| {
|
||||||
let mem =
|
let mem = Rc::new(
|
||||||
Rc::new(ClientMem::new(&map.keymap, map.keymap_len as _, true, None).unwrap())
|
ClientMem::new(&map.keymap, map.keymap_len as _, true, None, None).unwrap(),
|
||||||
.offset(0);
|
)
|
||||||
|
.offset(0);
|
||||||
mem.read(d.borrow_mut().deref_mut()).unwrap();
|
mem.read(d.borrow_mut().deref_mut()).unwrap();
|
||||||
});
|
});
|
||||||
self.tc.round_trip().await;
|
self.tc.round_trip().await;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
use {
|
use {
|
||||||
crate::{client::Client, utils::vec_ext::VecExt},
|
crate::{
|
||||||
|
client::Client,
|
||||||
|
cpu_worker::{AsyncCpuWork, CpuJob, CpuWork, CpuWorker},
|
||||||
|
utils::vec_ext::VecExt,
|
||||||
|
},
|
||||||
std::{
|
std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
mem::MaybeUninit,
|
mem::{ManuallyDrop, MaybeUninit},
|
||||||
ptr,
|
ptr,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
|
|
@ -25,10 +29,11 @@ pub enum ClientMemError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClientMem {
|
pub struct ClientMem {
|
||||||
fd: Rc<OwnedFd>,
|
fd: ManuallyDrop<Rc<OwnedFd>>,
|
||||||
failed: Cell<bool>,
|
failed: Cell<bool>,
|
||||||
sigbus_impossible: bool,
|
sigbus_impossible: bool,
|
||||||
data: *const [Cell<u8>],
|
data: *const [Cell<u8>],
|
||||||
|
cpu: Option<Rc<CpuWorker>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -44,6 +49,7 @@ impl ClientMem {
|
||||||
len: usize,
|
len: usize,
|
||||||
read_only: bool,
|
read_only: bool,
|
||||||
client: Option<&Client>,
|
client: Option<&Client>,
|
||||||
|
cpu: Option<&Rc<CpuWorker>>,
|
||||||
) -> Result<Self, ClientMemError> {
|
) -> Result<Self, ClientMemError> {
|
||||||
let mut sigbus_impossible = false;
|
let mut sigbus_impossible = false;
|
||||||
if let Ok(seals) = uapi::fcntl_get_seals(fd.raw()) {
|
if let Ok(seals) = uapi::fcntl_get_seals(fd.raw()) {
|
||||||
|
|
@ -78,10 +84,11 @@ impl ClientMem {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
fd: fd.clone(),
|
fd: ManuallyDrop::new(fd.clone()),
|
||||||
failed: Cell::new(false),
|
failed: Cell::new(false),
|
||||||
sigbus_impossible,
|
sigbus_impossible,
|
||||||
data,
|
data,
|
||||||
|
cpu: cpu.cloned(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,8 +162,17 @@ impl ClientMemOffset {
|
||||||
|
|
||||||
impl Drop for ClientMem {
|
impl Drop for ClientMem {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
let fd = unsafe { ManuallyDrop::take(&mut self.fd) };
|
||||||
c::munmap(self.data as _, self.len());
|
if let Some(cpu) = &self.cpu {
|
||||||
|
let pending = cpu.submit(Box::new(CloseMemWork {
|
||||||
|
fd: Rc::try_unwrap(fd).ok(),
|
||||||
|
data: self.data,
|
||||||
|
}));
|
||||||
|
pending.detach();
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
c::munmap(self.data as _, self.len());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -219,3 +235,30 @@ pub fn init() -> Result<(), ClientMemError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CloseMemWork {
|
||||||
|
fd: Option<OwnedFd>,
|
||||||
|
data: *const [Cell<u8>],
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for CloseMemWork {}
|
||||||
|
|
||||||
|
impl CpuJob for CloseMemWork {
|
||||||
|
fn work(&mut self) -> &mut dyn CpuWork {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completed(self: Box<Self>) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CpuWork for CloseMemWork {
|
||||||
|
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
|
||||||
|
self.fd.take();
|
||||||
|
unsafe {
|
||||||
|
c::munmap(self.data as _, self.data.len());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,6 @@ pub enum CpuWorkerError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingJob {
|
impl PendingJob {
|
||||||
#[expect(dead_code)]
|
|
||||||
pub fn detach(self) {
|
pub fn detach(self) {
|
||||||
match self.job_data.state.get() {
|
match self.job_data.state.get() {
|
||||||
PendingJobState::Waiting => {
|
PendingJobState::Waiting => {
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,14 @@ impl JayInput {
|
||||||
where
|
where
|
||||||
F: FnOnce(&Rc<XkbKeymap>) -> Result<(), JayInputError>,
|
F: FnOnce(&Rc<XkbKeymap>) -> Result<(), JayInputError>,
|
||||||
{
|
{
|
||||||
let cm = Rc::new(ClientMem::new(keymap, len as _, true, Some(&self.client))?).offset(0);
|
let cm = Rc::new(ClientMem::new(
|
||||||
|
keymap,
|
||||||
|
len as _,
|
||||||
|
true,
|
||||||
|
Some(&self.client),
|
||||||
|
None,
|
||||||
|
)?)
|
||||||
|
.offset(0);
|
||||||
let mut map = vec![];
|
let mut map = vec![];
|
||||||
cm.read(&mut map)?;
|
cm.read(&mut map)?;
|
||||||
self.or_error(|| {
|
self.or_error(|| {
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,15 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 {
|
||||||
if req.size > MAX_SIZE {
|
if req.size > MAX_SIZE {
|
||||||
return Err(ZwpVirtualKeyboardV1Error::OversizedKeymap);
|
return Err(ZwpVirtualKeyboardV1Error::OversizedKeymap);
|
||||||
}
|
}
|
||||||
let client_mem = ClientMem::new(&req.fd, req.size as usize - 1, true, Some(&self.client))
|
let client_mem = ClientMem::new(
|
||||||
.map(Rc::new)
|
&req.fd,
|
||||||
.map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?;
|
req.size as usize - 1,
|
||||||
|
true,
|
||||||
|
Some(&self.client),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.map(Rc::new)
|
||||||
|
.map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?;
|
||||||
let mut map = vec![];
|
let mut map = vec![];
|
||||||
client_mem
|
client_mem
|
||||||
.offset(0)
|
.offset(0)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,13 @@ impl WlShmPool {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
id,
|
id,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
mem: CloneCell::new(Rc::new(ClientMem::new(&fd, len, false, Some(client))?)),
|
mem: CloneCell::new(Rc::new(ClientMem::new(
|
||||||
|
&fd,
|
||||||
|
len,
|
||||||
|
false,
|
||||||
|
Some(client),
|
||||||
|
Some(&client.state.cpu_worker),
|
||||||
|
)?)),
|
||||||
fd,
|
fd,
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
version,
|
version,
|
||||||
|
|
@ -86,6 +92,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
|
||||||
req.size as usize,
|
req.size as usize,
|
||||||
false,
|
false,
|
||||||
Some(&self.client),
|
Some(&self.client),
|
||||||
|
Some(&self.client.state.cpu_worker),
|
||||||
)?));
|
)?));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_keymap(fd: &Rc<OwnedFd>, size: usize) -> String {
|
fn read_keymap(fd: &Rc<OwnedFd>, size: usize) -> String {
|
||||||
let client_mem = ClientMem::new(fd, size - 1, true, None).unwrap();
|
let client_mem = ClientMem::new(fd, size - 1, true, None, None).unwrap();
|
||||||
let client_mem = Rc::new(client_mem).offset(0);
|
let client_mem = Rc::new(client_mem).offset(0);
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
client_mem.read(&mut v).unwrap();
|
client_mem.read(&mut v).unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue