diff --git a/build/build.rs b/build/build.rs index 0740197a..cb484511 100644 --- a/build/build.rs +++ b/build/build.rs @@ -24,6 +24,6 @@ fn main() -> anyhow::Result<()> { enums::main()?; - println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=build/build.rs"); Ok(()) } diff --git a/build/wire.rs b/build/wire.rs index 134a80f5..392967e2 100644 --- a/build/wire.rs +++ b/build/wire.rs @@ -611,7 +611,7 @@ fn write_message(f: &mut W, obj: &BStr, message: &Message) -> Result<( writeln!(f, " }}")?; writeln!(f, " }}")?; writeln!(f, " impl EventFormatter for {}{} {{", message.camel_name, if has_reference_type { "Out" } else { "" })?; - writeln!(f, " fn format(self: Box, fmt: &mut MsgFormatter<'_>) {{")?; + writeln!(f, " fn format(self, fmt: &mut MsgFormatter<'_>) {{")?; writeln!(f, " fmt.header(self.self_id, {});", uppercase)?; fn write_fmt_expr(f: &mut W, prefix: &str, ty: &Type, access: &str) -> Result<()> { let p = match ty { diff --git a/src/client/mod.rs b/src/client/mod.rs index 6f92d28a..4c0b0ad7 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -6,7 +6,7 @@ use crate::ifs::wl_display::WlDisplay; use crate::ifs::wl_registry::{WlRegistry}; use crate::object::{Interface, Object, ObjectId, WL_DISPLAY_ID}; use crate::state::State; -use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError}; +use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain}; use crate::utils::numcell::NumCell; use crate::utils::oneshot::{oneshot, OneshotTx}; use crate::utils::queue::AsyncQueue; @@ -19,6 +19,7 @@ use std::fmt::{Debug, Display, Formatter}; use std::mem; use std::rc::Rc; use uapi::{c, OwnedFd}; +use crate::utils::asyncevent::AsyncEvent; use crate::wire::WlRegistryId; mod error; @@ -92,9 +93,9 @@ impl Clients { checking_queue_size: Cell::new(false), socket: global.eng.fd(&Rc::new(socket))?, objects: Objects::new(), - events: AsyncQueue::new(), + swapchain: Default::default(), + flush_request: Default::default(), shutdown: Cell::new(Some(send)), - shutdown_sent: Cell::new(false), dispatch_frame_requests: AsyncQueue::new(), }); let display = Rc::new(WlDisplay::new(&data)); @@ -126,8 +127,7 @@ impl Clients { if let Some(client) = self.clients.borrow_mut().remove(&client_id) { log::info!("Shutting down client {}", client.data.id.0); client.data.shutdown.replace(None).unwrap().send(()); - client.data.events.push(WlEvent::Shutdown); - client.data.shutdown_sent.set(true); + client.data.flush_request.trigger(); self.shutdown_clients.borrow_mut().insert(client_id, client); } } @@ -158,42 +158,33 @@ pub struct ClientHolder { impl Drop for ClientHolder { fn drop(&mut self) { self.data.objects.destroy(); - self.data.events.clear(); self.data.dispatch_frame_requests.clear(); } } pub trait EventFormatter: Debug { - fn format(self: Box, fmt: &mut MsgFormatter<'_>); + fn format(self, fmt: &mut MsgFormatter<'_>); fn id(&self) -> ObjectId; fn interface(&self) -> Interface; } -pub type DynEventFormatter = Box; - pub trait RequestParser<'a>: Debug + Sized { fn parse(parser: &mut MsgParser<'_, 'a>) -> Result; } -pub enum WlEvent { - Flush, - Shutdown, - Event(Box), -} - pub struct Client { pub id: ClientId, pub state: Rc, checking_queue_size: Cell, socket: AsyncFd, pub objects: Objects, - events: AsyncQueue, + swapchain: Rc>, + flush_request: AsyncEvent, shutdown: Cell>>, - shutdown_sent: Cell, pub dispatch_frame_requests: AsyncQueue>, } -const MAX_PENDING_EVENTS: usize = 10000; +const MAX_PENDING_BUFFERS: usize = 10; impl Client { pub fn invalid_request(&self, obj: &dyn Object, request: u32) { @@ -205,7 +196,10 @@ impl Client { obj.interface().name(), ); match self.display() { - Ok(d) => self.fatal_event(d.invalid_request(obj, request)), + Ok(d) => { + d.send_invalid_request(obj, request); + self.state.clients.shutdown(self.id); + }, Err(e) => { log::error!( "Could not retrieve display of client {}: {}", @@ -249,7 +243,10 @@ impl Client { let msg = ErrorFmt(message).to_string(); log::error!("Client {}: A fatal error occurred: {}", self.id.0, msg,); match self.display() { - Ok(d) => self.fatal_event(d.implementation_error(msg)), + Ok(d) => { + d.send_implementation_error(msg); + self.state.clients.shutdown(self.id); + }, Err(e) => { log::error!( "Could not retrieve display of client {}: {}", @@ -263,38 +260,39 @@ impl Client { pub fn protocol_error(&self, obj: &dyn Object, code: u32, message: String) { if let Ok(d) = self.display() { - self.fatal_event(d.error(obj.id(), code, message)); - } else { - self.state.clients.shutdown(self.id); + d.send_error(obj.id(), code, message); } - } - - pub fn fatal_event(&self, event: Box) { - self.events.push(WlEvent::Event(event)); self.state.clients.shutdown(self.id); } - pub fn event(self: &Rc, event: Box) { - self.event2(WlEvent::Event(event)); - } - - pub fn flush(self: &Rc) { - self.event2(WlEvent::Flush); - } - - pub fn event2(self: &Rc, event: WlEvent) { - self.events.push(event); - if self.events.size() > MAX_PENDING_EVENTS { - if !self.checking_queue_size.replace(true) { - self.state.slow_clients.push(self.clone()); + pub fn event(self: &Rc, event: T) { + if log::log_enabled!(log::Level::Trace) { + self.log_event(&event); + } + let mut fds = vec![]; + let mut swapchain = self.swapchain.borrow_mut(); + let mut fmt = MsgFormatter::new(&mut swapchain.cur, &mut fds); + event.format(&mut fmt); + fmt.write_len(); + if swapchain.cur.is_full() { + swapchain.commit(); + if swapchain.pending.len() > MAX_PENDING_BUFFERS { + if !self.checking_queue_size.replace(true) { + self.state.slow_clients.push(self.clone()); + } } + self.flush_request.trigger(); } } + pub fn flush(&self) { + self.flush_request.trigger(); + } + pub async fn check_queue_size(&self) { - if self.events.size() > MAX_PENDING_EVENTS { + if self.swapchain.borrow_mut().exceeds_limit() { self.state.eng.yield_now().await; - if self.events.size() > MAX_PENDING_EVENTS { + if self.swapchain.borrow_mut().exceeds_limit() { log::error!("Client {} is too slow at fetching events", self.id.0); self.state.clients.kill(self.id); return; @@ -307,7 +305,7 @@ impl Client { self.objects.registries() } - pub fn log_event(&self, event: &dyn EventFormatter) { + pub fn log_event(&self, event: &T) { log::trace!( "Client {} <= {}@{}.{:?}", self.id, diff --git a/src/client/objects.rs b/src/client/objects.rs index a72f3cfb..a4fb2b50 100644 --- a/src/client/objects.rs +++ b/src/client/objects.rs @@ -156,7 +156,7 @@ impl Objects { } ids[pos] |= 1 << seg_offset; } else { - client_data.event(client_data.display()?.delete_id(id)); + client_data.display()?.send_delete_id(id); } Ok(()) } diff --git a/src/client/tasks.rs b/src/client/tasks.rs index 656cb5cd..4fca295d 100644 --- a/src/client/tasks.rs +++ b/src/client/tasks.rs @@ -1,6 +1,7 @@ -use crate::client::{Client, ClientError, WlEvent}; +use std::collections::VecDeque; +use crate::client::{Client, ClientError}; use crate::object::ObjectId; -use crate::utils::buffd::{BufFdIn, BufFdOut, MsgFormatter, MsgParser}; +use crate::utils::buffd::{BufFdIn, BufFdOut, MsgParser}; use crate::utils::oneshot::OneshotRx; use crate::utils::vec_ext::VecExt; use crate::ErrorFmt; @@ -19,9 +20,7 @@ pub async fn client(data: Rc, shutdown: OneshotRx<()>) { } drop(recv); drop(dispatch_fr); - if !data.shutdown_sent.get() { - data.events.push(WlEvent::Shutdown); - } + data.flush_request.trigger(); match data.state.eng.timeout(5000) { Ok(timeout) => { timeout.await; @@ -38,7 +37,7 @@ async fn dispatch_fr(data: Rc) { loop { let mut fr = data.dispatch_frame_requests.pop().await; loop { - data.event(fr.done()); + fr.send_done(); if let Err(e) = data.remove_obj(&*fr) { log::error!("Could not remove frame object: {}", ErrorFmt(e)); return; @@ -66,7 +65,8 @@ async fn receive(data: Rc) { let obj = match data.objects.get_obj(obj_id) { Ok(obj) => obj, _ => { - data.fatal_event(display.invalid_object(obj_id)); + display.send_invalid_object(obj_id); + data.state.clients.shutdown(data.id); return Err(ClientError::InvalidObject(obj_id)); } }; @@ -109,49 +109,27 @@ async fn receive(data: Rc) { data.id.0, e ); - if !data.shutdown_sent.get() { - data.fatal_event(display.implementation_error(e.to_string())); - } + display.send_implementation_error(e.to_string()); + data.state.clients.shutdown(data.id); } } } async fn send(data: Rc) { let send = async { - let mut buf = BufFdOut::new(data.socket.clone()); - let mut flush_requested = false; + let mut out = BufFdOut::new(data.socket.clone()); + let mut buffers = VecDeque::new(); loop { - let mut event = data.events.pop().await; - loop { - match event { - WlEvent::Flush => { - flush_requested = true; - } - WlEvent::Shutdown => { - buf.flush().await?; - return Ok(()); - } - WlEvent::Event(e) => { - if log::log_enabled!(log::Level::Trace) { - data.log_event(&*e); - } - let mut fds = vec![]; - let mut fmt = MsgFormatter::new(&mut buf, &mut fds); - e.format(&mut fmt); - fmt.write_len(); - if buf.needs_flush() { - buf.flush().await?; - flush_requested = false; - } - } - } - event = match data.events.try_pop() { - Some(e) => e, - _ => break, - }; + data.flush_request.triggered().await; + { + let mut swapchain = data.swapchain.borrow_mut(); + swapchain.commit(); + mem::swap(&mut swapchain.pending, &mut buffers); } - if mem::take(&mut flush_requested) { - buf.flush().await?; + let mut timeout = None; + while let Some(mut cur) = buffers.pop_front() { + out.flush(&mut cur, &mut timeout).await?; + data.swapchain.borrow_mut().free.push(cur); } } }; diff --git a/src/globals.rs b/src/globals.rs index bb975bee..bb51144d 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, DynEventFormatter}; +use crate::client::{Client}; use crate::ifs::org_kde_kwin_server_decoration_manager::OrgKdeKwinServerDecorationManagerGlobal; use crate::ifs::wl_drm::WlDrmGlobal; use crate::ifs::wl_output::WlOutputGlobal; @@ -123,7 +123,7 @@ impl Globals { fn insert(&self, state: &State, global: Rc) { self.insert_no_broadcast_(&global); - self.broadcast(state, |r| r.global(&global)); + self.broadcast(state, |r| r.send_global(&global)); } pub fn get(&self, name: GlobalName) -> Result, GlobalsError> { @@ -133,7 +133,7 @@ impl Globals { pub fn remove(&self, state: &State, global: &T) -> Result<(), GlobalsError> { let _global = self.take(global.name(), true)?; global.remove(self); - self.broadcast(state, |r| r.global_remove(global.name())); + self.broadcast(state, |r| r.send_global_remove(global.name())); Ok(()) } @@ -141,13 +141,13 @@ impl Globals { self.seats.lock() } - pub fn notify_all(&self, client: &Rc, registry: &Rc) { + pub fn notify_all(&self, registry: &Rc) { let globals = self.registry.lock(); macro_rules! emit { ($singleton:expr) => { for global in globals.values() { if global.singleton() == $singleton { - client.event(registry.global(global)); + registry.send_global(global); } } }; @@ -156,11 +156,11 @@ impl Globals { emit!(false); } - fn broadcast) -> DynEventFormatter>(&self, state: &State, f: F) { + fn broadcast)>(&self, state: &State, f: F) { state.clients.broadcast(|c| { let registries = c.lock_registries(); for registry in registries.values() { - c.event(f(registry)); + f(registry); } c.flush(); }); diff --git a/src/ifs/org_kde_kwin_server_decoration.rs b/src/ifs/org_kde_kwin_server_decoration.rs index 1fd06f78..5aa4f89c 100644 --- a/src/ifs/org_kde_kwin_server_decoration.rs +++ b/src/ifs/org_kde_kwin_server_decoration.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::object::Object; use crate::utils::buffd::MsgParser; use std::cell::Cell; @@ -29,8 +29,8 @@ impl OrgKdeKwinServerDecoration { } } - pub fn mode(self: &Rc, mode: u32) -> DynEventFormatter { - Box::new(Mode { + pub fn send_mode(self: &Rc, mode: u32) { + self.client.event(Mode { self_id: self.id, mode, }) @@ -52,7 +52,7 @@ impl OrgKdeKwinServerDecoration { } else { SERVER }; - self.client.event(self.mode(mode)); + self.send_mode(mode); Ok(()) } } diff --git a/src/ifs/org_kde_kwin_server_decoration_manager.rs b/src/ifs/org_kde_kwin_server_decoration_manager.rs index aa305f40..81539437 100644 --- a/src/ifs/org_kde_kwin_server_decoration_manager.rs +++ b/src/ifs/org_kde_kwin_server_decoration_manager.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::globals::{Global, GlobalName}; use crate::ifs::org_kde_kwin_server_decoration::OrgKdeKwinServerDecoration; use crate::object::Object; @@ -35,7 +35,7 @@ impl OrgKdeKwinServerDecorationManagerGlobal { _version: version, }); client.add_client_obj(&obj)?; - client.event(obj.default_mode(SERVER)); + obj.send_default_mode(SERVER); Ok(()) } } @@ -65,8 +65,8 @@ pub struct OrgKdeKwinServerDecorationManager { } impl OrgKdeKwinServerDecorationManager { - fn default_mode(self: &Rc, mode: u32) -> DynEventFormatter { - Box::new(DefaultMode { + fn send_default_mode(self: &Rc, mode: u32) { + self.client.event(DefaultMode { self_id: self.id, mode, }) @@ -77,7 +77,7 @@ impl OrgKdeKwinServerDecorationManager { let _ = self.client.lookup(req.surface)?; let obj = Rc::new(OrgKdeKwinServerDecoration::new(req.id, &self.client)); self.client.add_client_obj(&obj)?; - self.client.event(obj.mode(SERVER)); + obj.send_mode(SERVER); Ok(()) } } diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index ab2d5004..1c6bde93 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::clientmem::{ClientMem, ClientMemOffset}; use crate::format::Format; use crate::object::Object; @@ -118,8 +118,8 @@ impl WlBuffer { Ok(()) } - pub fn release(&self) -> DynEventFormatter { - Box::new(Release { self_id: self.id }) + pub fn send_release(&self) { + self.client.event(Release { self_id: self.id }) } } diff --git a/src/ifs/wl_callback.rs b/src/ifs/wl_callback.rs index 831110cb..e0db5281 100644 --- a/src/ifs/wl_callback.rs +++ b/src/ifs/wl_callback.rs @@ -1,4 +1,4 @@ -use crate::client::DynEventFormatter; +use crate::client::{Client}; use crate::object::Object; use std::rc::Rc; use thiserror::Error; @@ -6,16 +6,17 @@ use crate::wire::wl_callback::*; use crate::wire::WlCallbackId; pub struct WlCallback { + client: Rc, id: WlCallbackId, } impl WlCallback { - pub fn new(id: WlCallbackId) -> Self { - Self { id } + pub fn new(id: WlCallbackId, client: &Rc) -> Self { + Self { client: client.clone(), id } } - pub fn done(self: &Rc) -> DynEventFormatter { - Box::new(Done { self_id: self.id, callback_data: 0 }) + pub fn send_done(&self) { + self.client.event(Done { self_id: self.id, callback_data: 0 }); } } diff --git a/src/ifs/wl_data_device.rs b/src/ifs/wl_data_device.rs index e442514e..3564293a 100644 --- a/src/ifs/wl_data_device.rs +++ b/src/ifs/wl_data_device.rs @@ -1,4 +1,4 @@ -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::ifs::wl_data_device_manager::WlDataDeviceManager; use crate::ifs::wl_seat::WlSeat; use crate::object::Object; @@ -28,15 +28,15 @@ impl WlDataDevice { } } - pub fn data_offer(self: &Rc, id: WlDataOfferId) -> DynEventFormatter { - Box::new(DataOffer { + pub fn send_data_offer(&self, id: WlDataOfferId) { + self.manager.client.event(DataOffer { self_id: self.id, id, }) } - pub fn selection(self: &Rc, id: WlDataOfferId) -> DynEventFormatter { - Box::new(Selection { + pub fn send_selection(&self, id: WlDataOfferId) { + self.manager.client.event(Selection { self_id: self.id, id, }) diff --git a/src/ifs/wl_data_offer.rs b/src/ifs/wl_data_offer.rs index 0789b683..a827b0e7 100644 --- a/src/ifs/wl_data_offer.rs +++ b/src/ifs/wl_data_offer.rs @@ -1,5 +1,5 @@ - -use crate::client::{Client, ClientError, DynEventFormatter}; +use std::mem; +use crate::client::{Client, ClientError}; use crate::ifs::wl_data_source::WlDataSource; use crate::ifs::wl_seat::WlSeatGlobal; use crate::object::Object; @@ -54,22 +54,29 @@ impl WlDataOffer { source: CloneCell::new(Some(src.clone())), }); let mt = src.mime_types.borrow_mut(); + let mut sent_offer = false; seat.for_each_data_device(0, client.id, |device| { - client.event(device.data_offer(slf.id)); - for mt in mt.deref() { - client.event(slf.offer(mt)); + if !mem::replace(&mut sent_offer, true) { + device.send_data_offer(slf.id); + } + for mt in mt.deref() { + slf.send_offer(mt); + } + match role { + DataOfferRole::Selection => device.send_selection(id), } - let ev = match role { - DataOfferRole::Selection => device.selection(id), - }; - client.event(ev); }); client.add_server_obj(&slf); - Some(slf) + if !sent_offer { + let _ = client.remove_obj(&*slf); + None + } else { + Some(slf) + } } - pub fn offer(self: &Rc, mime_type: &str) -> DynEventFormatter { - Box::new(OfferOut { + pub fn send_offer(self: &Rc, mime_type: &str) { + self.client.event(OfferOut { self_id: self.id, mime_type: mime_type.to_string(), }) @@ -83,7 +90,7 @@ impl WlDataOffer { fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> { let req: ReceiveIn = self.client.parse(self, parser)?; if let Some(src) = self.source.get() { - src.client.event(src.send(req.mime_type, req.fd)); + src.send_send(req.mime_type, req.fd); src.client.flush(); } Ok(()) diff --git a/src/ifs/wl_data_source.rs b/src/ifs/wl_data_source.rs index efbaf015..a3014ef4 100644 --- a/src/ifs/wl_data_source.rs +++ b/src/ifs/wl_data_source.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::ifs::wl_data_offer::{DataOfferRole, WlDataOffer}; use crate::ifs::wl_seat::WlSeatGlobal; use crate::object::Object; @@ -66,7 +66,7 @@ impl WlDataSource { if let Some(offer) = self.offer.set(None) { offer.source.set(None); } - self.client.event(self.cancelled()); + self.send_cancelled(); self.client.flush(); } @@ -89,12 +89,12 @@ impl WlDataSource { self.offer.take(); } - pub fn cancelled(self: &Rc) -> DynEventFormatter { - Box::new(Cancelled { self_id: self.id }) + pub fn send_cancelled(self: &Rc) { + self.client.event(Cancelled { self_id: self.id }) } - pub fn send(&self, mime_type: &str, fd: Rc) -> DynEventFormatter { - Box::new(SendOut { + pub fn send_send(&self, mime_type: &str, fd: Rc) { + self.client.event(SendOut { self_id: self.id, mime_type: mime_type.to_string(), fd, @@ -109,7 +109,7 @@ impl WlDataSource { .insert(req.mime_type.to_string()) { if let Some(offer) = self.offer.get() { - offer.client.event(offer.offer(req.mime_type)); + offer.send_offer(req.mime_type); } } Ok(()) diff --git a/src/ifs/wl_display.rs b/src/ifs/wl_display.rs index 877529cd..d754e05b 100644 --- a/src/ifs/wl_display.rs +++ b/src/ifs/wl_display.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::ifs::wl_callback::WlCallback; use crate::ifs::wl_registry::WlRegistry; use crate::object::{Object, ObjectId, WL_DISPLAY_ID}; @@ -32,9 +32,9 @@ impl WlDisplay { fn sync(&self, parser: MsgParser<'_, '_>) -> Result<(), SyncError> { let sync: Sync = self.client.parse(self, parser)?; - let cb = Rc::new(WlCallback::new(sync.callback)); + let cb = Rc::new(WlCallback::new(sync.callback, &self.client)); self.client.add_client_obj(&cb)?; - self.client.event(cb.done()); + cb.send_done(); self.client.remove_obj(&*cb)?; Ok(()) } @@ -46,17 +46,17 @@ impl WlDisplay { self.client .state .globals - .notify_all(&self.client, ®istry); + .notify_all(®istry); Ok(()) } - pub fn error>( - self: &Rc, + pub fn send_error>( + &self, object_id: O, code: u32, message: String, - ) -> DynEventFormatter { - Box::new(ErrorOut { + ) { + self.client.event(ErrorOut { self_id: self.id, object_id: object_id.into(), code, @@ -64,7 +64,7 @@ impl WlDisplay { }) } - pub fn invalid_request(self: &Rc, obj: &dyn Object, request: u32) -> DynEventFormatter { + pub fn send_invalid_request(self: &Rc, obj: &dyn Object, request: u32) { let id = obj.id(); let msg = format!( "Object {} of type {} has no method {}", @@ -72,20 +72,20 @@ impl WlDisplay { obj.interface().name(), request ); - self.error(id, INVALID_METHOD, msg) + self.send_error(id, INVALID_METHOD, msg) } - pub fn invalid_object(self: &Rc, id: ObjectId) -> DynEventFormatter { + pub fn send_invalid_object(self: &Rc, id: ObjectId) { let msg = format!("Object {} does not exist", id,); - self.error(id, INVALID_OBJECT, msg) + self.send_error(id, INVALID_OBJECT, msg) } - pub fn implementation_error(self: &Rc, msg: String) -> DynEventFormatter { - self.error(WL_DISPLAY_ID, IMPLEMENTATION, msg) + pub fn send_implementation_error(self: &Rc, msg: String) { + self.send_error(WL_DISPLAY_ID, IMPLEMENTATION, msg) } - pub fn delete_id(self: &Rc, id: ObjectId) -> DynEventFormatter { - Box::new(DeleteId { + pub fn send_delete_id(self: &Rc, id: ObjectId) { + self.client.event(DeleteId { self_id: self.id, id: id.raw(), }) diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index c0e438c7..e7a6f367 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::globals::{Global, GlobalName}; use crate::object::Object; use crate::utils::buffd::MsgParser; @@ -35,8 +35,8 @@ impl WlDrmGlobal { }); client.add_client_obj(&obj)?; if let Some(rc) = client.state.render_ctx.get() { - client.event(obj.device(&rc.render_node())); - client.event(obj.capabilities(PRIME)); + obj.send_device(&rc.render_node()); + obj.send_capabilities(PRIME); } Ok(()) } @@ -63,19 +63,19 @@ pub struct WlDrm { } impl WlDrm { - fn device(self: &Rc, device: &Rc) -> DynEventFormatter { - Box::new(DeviceOut { + fn send_device(self: &Rc, device: &Rc) { + self.client.event(DeviceOut { self_id: self.id, name: device.as_bytes().as_bstr().to_owned(), }) } - fn authenticated(self: &Rc) -> DynEventFormatter { - Box::new(Authenticated { self_id: self.id }) + fn send_authenticated(self: &Rc) { + self.client.event(Authenticated { self_id: self.id }) } - fn capabilities(self: &Rc, value: u32) -> DynEventFormatter { - Box::new(Capabilities { + fn send_capabilities(self: &Rc, value: u32) { + self.client.event(Capabilities { self_id: self.id, value, }) @@ -83,7 +83,7 @@ impl WlDrm { fn authenticate(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), AuthenticateError> { let _req: Authenticate = self.client.parse(&**self, parser)?; - self.client.event(self.authenticated()); + self.send_authenticated(); Ok(()) } diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index e6594cac..d47799e9 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -1,13 +1,12 @@ use crate::backend::Output; -use crate::client::{Client, ClientError, ClientId, DynEventFormatter, WlEvent}; +use crate::client::{Client, ClientError, ClientId}; use crate::globals::{Global, GlobalName}; use crate::object::Object; use crate::utils::buffd::MsgParser; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::collections::hash_map::Entry; -use std::iter; use std::rc::Rc; use thiserror::Error; use crate::wire::wl_output::*; @@ -81,19 +80,11 @@ impl WlOutputGlobal { let bindings = self.bindings.borrow_mut(); for binding in bindings.values() { for binding in binding.values() { - let events = [ - binding.geometry(), - binding.mode(), - binding.scale(), - binding.done(), - ]; - let events = events - .into_iter() - .map(|e| WlEvent::Event(e)) - .chain(iter::once(WlEvent::Flush)); - for event in events { - binding.client.event2(event); - } + binding.send_geometry(); + binding.send_mode(); + binding.send_scale(); + binding.send_done(); + binding.client.flush(); } } } @@ -117,13 +108,13 @@ impl WlOutputGlobal { .entry(client.id) .or_default() .insert(id, obj.clone()); - client.event(obj.geometry()); - client.event(obj.mode()); - if obj.send_scale() { - client.event(obj.scale()); + obj.send_geometry(); + obj.send_mode(); + if obj.version >= SEND_SCALE_SINCE { + obj.send_scale(); } - if obj.send_done() { - client.event(obj.done()); + if obj.version >= SEND_DONE_SINCE { + obj.send_done(); } Ok(()) } @@ -154,17 +145,12 @@ pub struct WlOutput { version: u32, } +pub const SEND_DONE_SINCE: u32 = 2; +pub const SEND_SCALE_SINCE: u32 = 2; + impl WlOutput { - fn send_done(&self) -> bool { - self.version >= 2 - } - - fn send_scale(&self) -> bool { - self.version >= 2 - } - - fn geometry(self: &Rc) -> DynEventFormatter { - Box::new(GeometryOut { + fn send_geometry(&self) { + let event = GeometryOut { self_id: self.id, x: 0, y: 0, @@ -174,28 +160,32 @@ impl WlOutput { make: "i4".to_string(), model: "i4".to_string(), transform: TF_NORMAL, - }) + }; + self.client.event(event); } - fn mode(self: &Rc) -> DynEventFormatter { - Box::new(Mode { + fn send_mode(&self) { + let event = Mode { self_id: self.id, flags: MODE_CURRENT, width: self.global.width.get() as _, height: self.global.height.get() as _, refresh: 60_000_000, - }) + }; + self.client.event(event); } - fn scale(self: &Rc) -> DynEventFormatter { - Box::new(Scale { + fn send_scale(self: &Rc) { + let event = Scale { self_id: self.id, factor: 1, - }) + }; + self.client.event(event); } - fn done(self: &Rc) -> DynEventFormatter { - Box::new(Done { self_id: self.id }) + fn send_done(&self) { + let event = Done { self_id: self.id }; + self.client.event(event); } fn remove_binding(&self) { diff --git a/src/ifs/wl_registry.rs b/src/ifs/wl_registry.rs index 97528d97..b63280ae 100644 --- a/src/ifs/wl_registry.rs +++ b/src/ifs/wl_registry.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, DynEventFormatter}; +use crate::client::{Client}; use crate::globals::{Global, GlobalName, GlobalsError}; use crate::object::{Interface, Object}; use crate::utils::buffd::MsgParser; @@ -22,8 +22,8 @@ impl WlRegistry { } } - pub fn global(self: &Rc, global: &Rc) -> DynEventFormatter { - Box::new(GlobalOut { + pub fn send_global(self: &Rc, global: &Rc) { + self.client.event(GlobalOut { self_id: self.id, name: global.name().raw(), interface: global.interface().name().to_string(), @@ -31,8 +31,8 @@ impl WlRegistry { }) } - pub fn global_remove(self: &Rc, name: GlobalName) -> DynEventFormatter { - Box::new(GlobalRemove { + pub fn send_global_remove(self: &Rc, name: GlobalName) { + self.client.event(GlobalRemove { self_id: self.id, name: name.raw(), }) diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 1777c5b1..5ef1ccd0 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -4,7 +4,7 @@ pub mod wl_pointer; pub mod wl_touch; use crate::backend::{Seat, SeatId}; -use crate::client::{Client, ClientError, ClientId, DynEventFormatter}; +use crate::client::{Client, ClientError, ClientId}; use crate::cursor::{Cursor, KnownCursor}; use crate::fixed::Fixed; use crate::globals::{Global, GlobalName}; @@ -174,7 +174,7 @@ impl WlSeatGlobal { } _ => { self.for_each_data_device(0, client.id, |device| { - client.event(device.selection(WlDataOfferId::NONE)); + device.send_selection(WlDataOfferId::NONE); }); } } @@ -200,7 +200,7 @@ impl WlSeatGlobal { } _ => { self.for_each_primary_selection_device(0, client.id, |device| { - client.event(device.selection(ZwpPrimarySelectionOfferV1Id::NONE)); + device.send_selection(ZwpPrimarySelectionOfferV1Id::NONE); }); } } @@ -264,9 +264,9 @@ impl WlSeatGlobal { version, }); client.add_client_obj(&obj)?; - client.event(obj.capabilities()); + obj.send_capabilities(); if version >= SEAT_NAME_SINCE { - client.event(obj.name(&self.seat_name)); + obj.send_name(&self.seat_name); } { let mut bindings = self.bindings.borrow_mut(); @@ -297,23 +297,23 @@ dedicated_add_global!(WlSeatGlobal, seats); pub struct WlSeat { pub global: Rc, - id: WlSeatId, - client: Rc, + pub id: WlSeatId, + pub client: Rc, pointers: CopyHashMap>, keyboards: CopyHashMap>, version: u32, } impl WlSeat { - fn capabilities(self: &Rc) -> DynEventFormatter { - Box::new(Capabilities { + fn send_capabilities(self: &Rc) { + self.client.event(Capabilities { self_id: self.id, capabilities: POINTER | KEYBOARD, }) } - fn name(self: &Rc, name: &Rc) -> DynEventFormatter { - Box::new(NameOut { + fn send_name(self: &Rc, name: &Rc) { + self.client.event(NameOut { self_id: self.id, name: name.deref().clone(), }) @@ -370,10 +370,9 @@ impl WlSeat { let p = Rc::new(WlKeyboard::new(req.id, self)); self.client.add_client_obj(&p)?; self.keyboards.set(req.id, p.clone()); - self.client - .event(p.keymap(wl_keyboard::XKB_V1, p.keymap_fd()?, self.global.layout_size)); + p.send_keymap(wl_keyboard::XKB_V1, p.keymap_fd()?, self.global.layout_size); if self.version >= REPEAT_INFO_SINCE { - self.client.event(p.repeat_info(25, 250)); + p.send_repeat_info(25, 250); } Ok(()) } diff --git a/src/ifs/wl_seat/handling.rs b/src/ifs/wl_seat/handling.rs index 4b9580d7..4ba4c2ac 100644 --- a/src/ifs/wl_seat/handling.rs +++ b/src/ifs/wl_seat/handling.rs @@ -1,5 +1,5 @@ use crate::backend::{KeyState, OutputId, ScrollAxis, SeatEvent, SeatId}; -use crate::client::{ClientId, DynEventFormatter}; +use crate::client::{ClientId}; use crate::fixed::Fixed; use crate::ifs::wl_data_device::WlDataDevice; use crate::ifs::wl_seat::wl_keyboard::WlKeyboard; @@ -229,7 +229,7 @@ impl WlSeatGlobal { let pressed_keys: Vec<_> = self.pressed_keys.borrow().iter().copied().collect(); let serial = self.serial.fetch_add(1); self.surface_kb_event(0, &surface, |k| { - k.enter(serial, surface.id, pressed_keys.clone()) + k.send_enter(serial, surface.id, pressed_keys.clone()) }); let ModifierState { mods_depressed, @@ -239,14 +239,14 @@ impl WlSeatGlobal { } = self.kb_state.borrow().mods(); let serial = self.serial.fetch_add(1); self.surface_kb_event(0, &surface, |k| { - k.modifiers(serial, mods_depressed, mods_latched, mods_locked, group) + k.send_modifiers(serial, mods_depressed, mods_latched, mods_locked, group) }); if old.client_id() != Some(surface.client.id) { match self.selection.get() { None => { self.surface_data_device_event(0, &surface, |dd| { - dd.selection(WlDataOfferId::NONE) + dd.send_selection(WlDataOfferId::NONE) }); } Some(sel) => { @@ -256,7 +256,7 @@ impl WlSeatGlobal { match self.primary_selection.get() { None => { self.surface_primary_selection_device_event(0, &surface, |dd| { - dd.selection(ZwpPrimarySelectionOfferV1Id::NONE) + dd.send_selection(ZwpPrimarySelectionOfferV1Id::NONE) }); } Some(sel) => { @@ -333,49 +333,49 @@ impl WlSeatGlobal { } fn surface_pointer_frame(&self, surface: &WlSurface) { - self.surface_pointer_event(POINTER_FRAME_SINCE_VERSION, surface, |p| p.frame()); + self.surface_pointer_event(POINTER_FRAME_SINCE_VERSION, surface, |p| p.send_frame()); } fn surface_pointer_event(&self, ver: u32, surface: &WlSurface, mut f: F) where - F: FnMut(&Rc) -> DynEventFormatter, + F: FnMut(&Rc), { let client = &surface.client; self.for_each_pointer(ver, client.id, |p| { - client.event(f(p)); + f(p); }); client.flush(); } fn surface_kb_event(&self, ver: u32, surface: &WlSurface, mut f: F) where - F: FnMut(&Rc) -> DynEventFormatter, + F: FnMut(&Rc), { let client = &surface.client; self.for_each_kb(ver, client.id, |p| { - client.event(f(p)); + f(p); }); client.flush(); } fn surface_data_device_event(&self, ver: u32, surface: &WlSurface, mut f: F) where - F: FnMut(&Rc) -> DynEventFormatter, + F: FnMut(&Rc), { let client = &surface.client; self.for_each_data_device(ver, client.id, |p| { - client.event(f(p)); + f(p); }); client.flush(); } fn surface_primary_selection_device_event(&self, ver: u32, surface: &WlSurface, mut f: F) where - F: FnMut(&Rc) -> DynEventFormatter, + F: FnMut(&Rc), { let client = &surface.client; self.for_each_primary_selection_device(ver, client.id, |p| { - client.event(f(p)); + f(p); }); client.flush(); } @@ -487,7 +487,7 @@ impl WlSeatGlobal { KeyState::Pressed => (wl_pointer::PRESSED, true), }; let serial = self.serial.fetch_add(1); - self.surface_pointer_event(0, surface, |p| p.button(serial, 0, button, state)); + self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state)); self.surface_pointer_frame(surface); if pressed && surface.belongs_to_toplevel() { self.focus_surface(surface); @@ -502,7 +502,7 @@ impl WlSeatGlobal { ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL, ScrollAxis::Vertical => wl_pointer::VERTICAL_SCROLL, }; - self.surface_pointer_event(0, surface, |p| p.axis(0, axis, Fixed::from_int(delta))); + self.surface_pointer_event(0, surface, |p| p.send_axis(0, axis, Fixed::from_int(delta))); self.surface_pointer_frame(surface); } } @@ -510,7 +510,7 @@ impl WlSeatGlobal { // Motion callbacks impl WlSeatGlobal { pub fn motion_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) { - self.surface_pointer_event(0, n, |p| p.motion(0, x, y)); + self.surface_pointer_event(0, n, |p| p.send_motion(0, x, y)); self.surface_pointer_frame(n); } } @@ -527,7 +527,7 @@ impl WlSeatGlobal { pub fn enter_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) { let serial = self.serial.fetch_add(1); - self.surface_pointer_event(0, n, |p| p.enter(serial, n.id, x, y)); + self.surface_pointer_event(0, n, |p| p.send_enter(serial, n.id, x, y)); self.surface_pointer_frame(n); } } @@ -536,7 +536,7 @@ impl WlSeatGlobal { impl WlSeatGlobal { pub fn leave_surface(&self, n: &WlSurface) { let serial = self.serial.fetch_add(1); - self.surface_pointer_event(0, n, |p| p.leave(serial, n.id)); + self.surface_pointer_event(0, n, |p| p.send_leave(serial, n.id)); self.surface_pointer_frame(n); } } @@ -544,7 +544,7 @@ impl WlSeatGlobal { // Unfocus callbacks impl WlSeatGlobal { pub fn unfocus_surface(&self, surface: &WlSurface) { - self.surface_kb_event(0, surface, |k| k.leave(0, surface.id)) + self.surface_kb_event(0, surface, |k| k.send_leave(0, surface.id)) } } @@ -558,11 +558,11 @@ impl WlSeatGlobal { mods: Option, ) { let serial = self.serial.fetch_add(1); - self.surface_kb_event(0, surface, |k| k.key(serial, 0, key, state)); + self.surface_kb_event(0, surface, |k| k.send_key(serial, 0, key, state)); let serial = self.serial.fetch_add(1); if let Some(mods) = mods { self.surface_kb_event(0, surface, |k| { - k.modifiers( + k.send_modifiers( serial, mods.mods_depressed, mods.mods_latched, diff --git a/src/ifs/wl_seat/wl_keyboard.rs b/src/ifs/wl_seat/wl_keyboard.rs index 3cf0108b..4de4a294 100644 --- a/src/ifs/wl_seat/wl_keyboard.rs +++ b/src/ifs/wl_seat/wl_keyboard.rs @@ -1,5 +1,5 @@ -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::ifs::wl_seat::WlSeat; use crate::object::Object; use crate::utils::buffd::MsgParser; @@ -62,8 +62,8 @@ impl WlKeyboard { Ok(Rc::new(fd)) } - pub fn keymap(self: &Rc, format: u32, fd: Rc, size: u32) -> DynEventFormatter { - Box::new(Keymap { + pub fn send_keymap(self: &Rc, format: u32, fd: Rc, size: u32) { + self.seat.client.event(Keymap { self_id: self.id, format, fd, @@ -71,13 +71,13 @@ impl WlKeyboard { }) } - pub fn enter( + pub fn send_enter( self: &Rc, serial: u32, surface: WlSurfaceId, keys: Vec, - ) -> DynEventFormatter { - Box::new(EnterOut { + ) { + self.seat.client.event(EnterOut { self_id: self.id, serial, surface, @@ -85,16 +85,16 @@ impl WlKeyboard { }) } - pub fn leave(self: &Rc, serial: u32, surface: WlSurfaceId) -> DynEventFormatter { - Box::new(Leave { + pub fn send_leave(self: &Rc, serial: u32, surface: WlSurfaceId) { + self.seat.client.event(Leave { self_id: self.id, serial, surface, }) } - pub fn key(self: &Rc, serial: u32, time: u32, key: u32, state: u32) -> DynEventFormatter { - Box::new(Key { + pub fn send_key(self: &Rc, serial: u32, time: u32, key: u32, state: u32) { + self.seat.client.event(Key { self_id: self.id, serial, time, @@ -103,15 +103,15 @@ impl WlKeyboard { }) } - pub fn modifiers( + pub fn send_modifiers( self: &Rc, serial: u32, mods_depressed: u32, mods_latched: u32, mods_locked: u32, group: u32, - ) -> DynEventFormatter { - Box::new(Modifiers { + ) { + self.seat.client.event(Modifiers { self_id: self.id, serial, mods_depressed, @@ -121,8 +121,8 @@ impl WlKeyboard { }) } - pub fn repeat_info(self: &Rc, rate: i32, delay: i32) -> DynEventFormatter { - Box::new(RepeatInfo { + pub fn send_repeat_info(self: &Rc, rate: i32, delay: i32) { + self.seat.client.event(RepeatInfo { self_id: self.id, rate, delay, diff --git a/src/ifs/wl_seat/wl_pointer.rs b/src/ifs/wl_seat/wl_pointer.rs index 03f95075..bbd61b3b 100644 --- a/src/ifs/wl_seat/wl_pointer.rs +++ b/src/ifs/wl_seat/wl_pointer.rs @@ -1,5 +1,5 @@ -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::cursor::Cursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::WlSeat; @@ -45,14 +45,14 @@ impl WlPointer { } } - pub fn enter( - self: &Rc, + pub fn send_enter( + &self, serial: u32, surface: WlSurfaceId, x: Fixed, y: Fixed, - ) -> DynEventFormatter { - Box::new(Enter { + ) { + self.seat.client.event(Enter { self_id: self.id, serial, surface, @@ -61,16 +61,16 @@ impl WlPointer { }) } - pub fn leave(self: &Rc, serial: u32, surface: WlSurfaceId) -> DynEventFormatter { - Box::new(Leave { + pub fn send_leave(&self, serial: u32, surface: WlSurfaceId) { + self.seat.client.event(Leave { self_id: self.id, serial, surface, }) } - pub fn motion(self: &Rc, time: u32, x: Fixed, y: Fixed) -> DynEventFormatter { - Box::new(Motion { + pub fn send_motion(&self, time: u32, x: Fixed, y: Fixed) { + self.seat.client.event(Motion { self_id: self.id, time, surface_x: x, @@ -78,14 +78,14 @@ impl WlPointer { }) } - pub fn button( - self: &Rc, + pub fn send_button( + &self, serial: u32, time: u32, button: u32, state: u32, - ) -> DynEventFormatter { - Box::new(Button { + ) { + self.seat.client.event(Button { self_id: self.id, serial, time, @@ -94,8 +94,8 @@ impl WlPointer { }) } - pub fn axis(self: &Rc, time: u32, axis: u32, value: Fixed) -> DynEventFormatter { - Box::new(Axis { + pub fn send_axis(&self, time: u32, axis: u32, value: Fixed) { + self.seat.client.event(Axis { self_id: self.id, time, axis, @@ -104,21 +104,21 @@ impl WlPointer { } #[allow(dead_code)] - pub fn frame(self: &Rc) -> DynEventFormatter { - Box::new(Frame { self_id: self.id }) + pub fn send_frame(&self) { + self.seat.client.event(Frame { self_id: self.id }) } #[allow(dead_code)] - pub fn axis_source(self: &Rc, axis_source: u32) -> DynEventFormatter { - Box::new(AxisSource { + pub fn send_axis_source(&self, axis_source: u32) { + self.seat.client.event(AxisSource { self_id: self.id, axis_source, }) } #[allow(dead_code)] - pub fn axis_stop(self: &Rc, time: u32, axis: u32) -> DynEventFormatter { - Box::new(AxisStop { + pub fn send_axis_stop(&self, time: u32, axis: u32) { + self.seat.client.event(AxisStop { self_id: self.id, time, axis, @@ -126,8 +126,8 @@ impl WlPointer { } #[allow(dead_code)] - pub fn axis_discrete(self: &Rc, axis: u32, discrete: i32) -> DynEventFormatter { - Box::new(AxisDiscrete { + pub fn send_axis_discrete(&self, axis: u32, discrete: i32) { + self.seat.client.event(AxisDiscrete { self_id: self.id, axis, discrete, diff --git a/src/ifs/wl_shm.rs b/src/ifs/wl_shm.rs index 97d70b79..04cd6ccf 100644 --- a/src/ifs/wl_shm.rs +++ b/src/ifs/wl_shm.rs @@ -39,10 +39,10 @@ impl WlShmGlobal { }); client.add_client_obj(&obj)?; for format in FORMATS { - client.event(Box::new(Format { + client.event(Format { self_id: id, format: format.wl_id.unwrap_or(format.drm), - })); + }); } Ok(()) } diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 03f38681..5f8170eb 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -3,7 +3,7 @@ pub mod wl_subsurface; pub mod xdg_surface; use crate::backend::{KeyState, ScrollAxis, SeatId}; -use crate::client::{Client, ClientError, DynEventFormatter, RequestParser}; +use crate::client::{Client, ClientError, RequestParser}; use crate::fixed::Fixed; use crate::ifs::wl_buffer::WlBuffer; use crate::ifs::wl_callback::WlCallback; @@ -212,8 +212,8 @@ impl WlSurface { false } - fn enter_event(self: &Rc, output: WlOutputId) -> DynEventFormatter { - Box::new(Enter { + fn send_enter(&self, output: WlOutputId) { + self.client.event(Enter { self_id: self.id, output, }) @@ -346,7 +346,7 @@ impl WlSurface { fn frame(&self, parser: MsgParser<'_, '_>) -> Result<(), FrameError> { let req: Frame = self.parse(parser)?; - let cb = Rc::new(WlCallback::new(req.callback)); + let cb = Rc::new(WlCallback::new(req.callback, &self.client)); self.client.add_client_obj(&cb)?; self.pending.frame_request.borrow_mut().push(cb); Ok(()) @@ -393,7 +393,7 @@ impl WlSurface { if let Some(buffer) = self.buffer.take() { old_size = Some(buffer.rect); if !buffer.destroyed() { - self.client.event(buffer.release()); + buffer.send_release(); } } if let Some((dx, dy, buffer)) = buffer_change { diff --git a/src/ifs/wl_surface/xdg_surface.rs b/src/ifs/wl_surface/xdg_surface.rs index 0b948709..7cb693fe 100644 --- a/src/ifs/wl_surface/xdg_surface.rs +++ b/src/ifs/wl_surface/xdg_surface.rs @@ -2,7 +2,7 @@ pub mod xdg_popup; pub mod xdg_toplevel; use crate::backend::SeatId; -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopup, XdgPopupError}; use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel; @@ -181,13 +181,13 @@ impl XdgSurface { self.geometry.get() } - pub fn send_configure(self: &Rc) { + pub fn do_send_configure(&self) { let serial = self.requested_serial.fetch_add(1) + 1; - self.surface.client.event(self.configure(serial)); + self.send_configure(serial); } - pub fn configure(self: &Rc, serial: u32) -> DynEventFormatter { - Box::new(Configure { + pub fn send_configure(&self, serial: u32) { + self.surface.client.event(Configure { self_id: self.id, serial, }) @@ -356,7 +356,7 @@ impl SurfaceExt for XdgSurface { if let Some(ext) = self.ext.get() { ext.initial_configure()?; } - self.surface.client.event(self.configure(rse)); + self.send_configure(rse); } // return CommitAction::AbortCommit; } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index f28f3da6..108d6843 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; @@ -58,8 +58,8 @@ impl XdgPopup { }) } - fn configure(self: &Rc, x: i32, y: i32, width: i32, height: i32) -> DynEventFormatter { - Box::new(Configure { + fn send_configure(&self, x: i32, y: i32, width: i32, height: i32) { + self.xdg.surface.client.event(Configure { self_id: self.id, x, y, @@ -68,15 +68,15 @@ impl XdgPopup { }) } - fn repositioned(self: &Rc, token: u32) -> DynEventFormatter { - Box::new(Repositioned { + fn send_repositioned(&self, token: u32) { + self.xdg.surface.client.event(Repositioned { self_id: self.id, token, }) } - fn popup_done(self: &Rc) -> DynEventFormatter { - Box::new(PopupDone { self_id: self.id }) + fn send_popup_done(&self) { + self.xdg.surface.client.event(PopupDone { self_id: self.id }) } fn update_position(&self, parent: &XdgSurface) -> Result<(), XdgPopupError> { @@ -205,14 +205,14 @@ impl XdgPopup { if let Some(parent) = self.parent.get() { self.update_position(&parent)?; let rel = self.relative_position.get(); - self.xdg.surface.client.event(self.repositioned(req.token)); - self.xdg.surface.client.event(self.configure( + self.send_repositioned(req.token); + self.send_configure( rel.x1(), rel.y1(), rel.width(), rel.height(), - )); - self.xdg.send_configure(); + ); + self.xdg.do_send_configure(); } Ok(()) } @@ -303,12 +303,12 @@ impl XdgSurfaceExt for XdgPopup { if let Some(parent) = self.parent.get() { self.update_position(&parent)?; let rel = self.relative_position.get(); - self.xdg.surface.client.event(self.configure( + self.send_configure( rel.x1(), rel.y1(), rel.width(), rel.height(), - )); + ); } Ok(()) } @@ -335,7 +335,7 @@ impl XdgSurfaceExt for XdgPopup { } else { if wl.take().is_some() { self.destroy_node(true); - surface.client.event(self.popup_done()); + self.send_popup_done(); } } } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 18b7c3e4..2957c640 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -1,7 +1,7 @@ use crate::backend::SeatId; use crate::bugs::Bugs; -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; @@ -117,11 +117,8 @@ impl XdgToplevel { }; if changed { let rect = self.xdg.absolute_desired_extents.get(); - self.xdg - .surface - .client - .event(self.configure_checked(rect.width(), rect.height())); - self.xdg.send_configure(); + self.send_configure_checked(rect.width(), rect.height()); + self.xdg.do_send_configure(); } } @@ -132,7 +129,7 @@ impl XdgToplevel { false } - fn configure_checked(self: &Rc, mut width: i32, mut height: i32) -> DynEventFormatter { + fn send_configure_checked(&self, mut width: i32, mut height: i32) { width = width.max(1); height = height.max(1); if self.bugs.get().respect_min_max_size { @@ -149,11 +146,11 @@ impl XdgToplevel { height = height.min(max); } } - self.configure(width, height) + self.send_configure(width, height) } - fn configure(self: &Rc, width: i32, height: i32) -> DynEventFormatter { - Box::new(ConfigureOut { + fn send_configure(&self, width: i32, height: i32) { + self.xdg.surface.client.event(ConfigureOut { self_id: self.id, width, height, @@ -447,11 +444,8 @@ impl Node for XdgToplevel { let nh = rect.height(); let de = self.xdg.absolute_desired_extents.get(); if de.width() != nw || de.height() != nh { - self.xdg - .surface - .client - .event(self.configure_checked(nw, nh)); - self.xdg.send_configure(); + self.send_configure_checked(nw, nh); + self.xdg.do_send_configure(); self.xdg.surface.client.flush(); } self.xdg.set_absolute_desired_extents(rect); @@ -468,7 +462,7 @@ impl Node for XdgToplevel { impl XdgSurfaceExt for XdgToplevel { fn initial_configure(self: Rc) -> Result<(), XdgSurfaceError> { - self.xdg.surface.client.event(self.configure(0, 0)); + self.send_configure(0, 0); Ok(()) } @@ -498,10 +492,7 @@ impl XdgSurfaceExt for XdgToplevel { let bindings = output.global.bindings.borrow_mut(); for binding in bindings.get(&self.xdg.surface.client.id) { for binding in binding.values() { - self.xdg - .surface - .client - .event(self.xdg.surface.enter_event(binding.id)); + self.xdg.surface.send_enter(binding.id); } } } diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index 95a52615..ccfbff56 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -1,4 +1,4 @@ -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::drm::dma::{DmaBuf, DmaBufPlane}; use crate::drm::INVALID_MODIFIER; use crate::ifs::wl_buffer::{WlBuffer}; @@ -25,8 +25,8 @@ const BOTTOM_FIRST: u32 = 4; const MAX_PLANE: u32 = 3; pub struct ZwpLinuxBufferParamsV1 { - id: ZwpLinuxBufferParamsV1Id, - parent: Rc, + pub id: ZwpLinuxBufferParamsV1Id, + pub parent: Rc, planes: RefCell>, used: Cell, } @@ -41,15 +41,15 @@ impl ZwpLinuxBufferParamsV1 { } } - fn created(self: &Rc, buffer_id: WlBufferId) -> DynEventFormatter { - Box::new(Created { + fn send_created(&self, buffer_id: WlBufferId) { + self.parent.client.event(Created { self_id: self.id, buffer: buffer_id, }) } - fn failed(self: &Rc) -> DynEventFormatter { - Box::new(Failed { self_id: self.id }) + fn send_failed(&self) { + self.parent.client.event(Failed { self_id: self.id }) } fn destroy(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> { @@ -136,11 +136,11 @@ impl ZwpLinuxBufferParamsV1 { } match self.do_create(None, req.width, req.height, req.format, req.flags) { Ok(id) => { - self.parent.client.event(self.created(id)); + self.send_created(id); } Err(e) => { log::debug!("Could not create a dmabuf buffer: {}", ErrorFmt(e)); - self.parent.client.event(self.failed()); + self.send_failed(); } } Ok(()) diff --git a/src/ifs/zwp_linux_dmabuf_v1.rs b/src/ifs/zwp_linux_dmabuf_v1.rs index 0a6cc9e1..b281f33e 100644 --- a/src/ifs/zwp_linux_dmabuf_v1.rs +++ b/src/ifs/zwp_linux_dmabuf_v1.rs @@ -1,4 +1,4 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::drm::INVALID_MODIFIER; use crate::globals::{Global, GlobalName}; use crate::ifs::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1; @@ -35,9 +35,9 @@ impl ZwpLinuxDmabufV1Global { if let Some(ctx) = client.state.render_ctx.get() { let formats = ctx.formats(); for format in formats.values() { - client.event(obj.format(format.drm)); + obj.send_format(format.drm); if version >= MODIFIERS_SINCE_VERSION { - client.event(obj.modifier(format.drm, INVALID_MODIFIER)); + obj.send_modifier(format.drm, INVALID_MODIFIER); } } } @@ -72,15 +72,15 @@ pub struct ZwpLinuxDmabufV1 { } impl ZwpLinuxDmabufV1 { - fn format(self: &Rc, format: u32) -> DynEventFormatter { - Box::new(Format { + fn send_format(&self, format: u32) { + self.client.event(Format { self_id: self.id, format, }) } - fn modifier(self: &Rc, format: u32, modifier: u64) -> DynEventFormatter { - Box::new(Modifier { + fn send_modifier(&self, format: u32, modifier: u64) { + self.client.event(Modifier { self_id: self.id, format, modifier_hi: (modifier >> 32) as _, diff --git a/src/ifs/zwp_primary_selection_device_v1.rs b/src/ifs/zwp_primary_selection_device_v1.rs index defb0bb1..0b6515db 100644 --- a/src/ifs/zwp_primary_selection_device_v1.rs +++ b/src/ifs/zwp_primary_selection_device_v1.rs @@ -1,5 +1,5 @@ -use crate::client::{ClientError, DynEventFormatter}; +use crate::client::{ClientError}; use crate::ifs::wl_seat::WlSeat; use crate::ifs::zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1; use crate::object::Object; @@ -29,15 +29,15 @@ impl ZwpPrimarySelectionDeviceV1 { } } - pub fn data_offer(self: &Rc, offer: ZwpPrimarySelectionOfferV1Id) -> DynEventFormatter { - Box::new(DataOffer { + pub fn send_data_offer(&self, offer: ZwpPrimarySelectionOfferV1Id) { + self.manager.client.event(DataOffer { self_id: self.id, offer, }) } - pub fn selection(self: &Rc, id: ZwpPrimarySelectionOfferV1Id) -> DynEventFormatter { - Box::new(Selection { + pub fn send_selection(&self, id: ZwpPrimarySelectionOfferV1Id) { + self.manager.client.event(Selection { self_id: self.id, id, }) diff --git a/src/ifs/zwp_primary_selection_offer_v1.rs b/src/ifs/zwp_primary_selection_offer_v1.rs index a926e4bd..84e84706 100644 --- a/src/ifs/zwp_primary_selection_offer_v1.rs +++ b/src/ifs/zwp_primary_selection_offer_v1.rs @@ -1,5 +1,5 @@ - -use crate::client::{Client, ClientError, DynEventFormatter}; +use std::mem; +use crate::client::{Client, ClientError}; use crate::ifs::wl_seat::WlSeatGlobal; use crate::ifs::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1; use crate::object::Object; @@ -36,19 +36,27 @@ impl ZwpPrimarySelectionOfferV1 { source: CloneCell::new(Some(src.clone())), }); let mt = src.mime_types.borrow_mut(); + let mut sent_offer = false; seat.for_each_primary_selection_device(0, client.id, |device| { - client.event(device.data_offer(slf.id)); - for mt in mt.deref() { - client.event(slf.offer(mt)); + if !mem::replace(&mut sent_offer, true) { + device.send_data_offer(slf.id); } - client.event(device.selection(id)); + for mt in mt.deref() { + slf.send_offer(mt); + } + device.send_selection(id); }); client.add_server_obj(&slf); - Some(slf) + if !sent_offer { + let _ = client.remove_obj(&*slf); + None + } else { + Some(slf) + } } - pub fn offer(self: &Rc, mime_type: &str) -> DynEventFormatter { - Box::new(OfferOut { + pub fn send_offer(self: &Rc, mime_type: &str) { + self.client.event(OfferOut { self_id: self.id, mime_type: mime_type.to_string(), }) @@ -57,7 +65,7 @@ impl ZwpPrimarySelectionOfferV1 { fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> { let req: ReceiveIn = self.client.parse(self, parser)?; if let Some(src) = self.source.get() { - src.client.event(src.send(req.mime_type, req.fd)); + src.send_send(req.mime_type, req.fd); src.client.flush(); } Ok(()) diff --git a/src/ifs/zwp_primary_selection_source_v1.rs b/src/ifs/zwp_primary_selection_source_v1.rs index 0f89b7e1..79162068 100644 --- a/src/ifs/zwp_primary_selection_source_v1.rs +++ b/src/ifs/zwp_primary_selection_source_v1.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::ifs::wl_seat::WlSeatGlobal; use crate::ifs::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1; use crate::object::Object; @@ -45,7 +45,7 @@ impl ZwpPrimarySelectionSourceV1 { if let Some(offer) = self.offer.set(None) { offer.source.set(None); } - self.client.event(self.cancelled()); + self.send_cancelled(); self.client.flush(); } @@ -68,12 +68,12 @@ impl ZwpPrimarySelectionSourceV1 { self.offer.take(); } - pub fn cancelled(self: &Rc) -> DynEventFormatter { - Box::new(Cancelled { self_id: self.id }) + pub fn send_cancelled(&self) { + self.client.event(Cancelled { self_id: self.id }) } - pub fn send(self: &Rc, mime_type: &str, fd: Rc) -> DynEventFormatter { - Box::new(SendOut { + pub fn send_send(&self, mime_type: &str, fd: Rc) { + self.client.event(SendOut { self_id: self.id, mime_type: mime_type.to_string(), fd, @@ -88,7 +88,7 @@ impl ZwpPrimarySelectionSourceV1 { .insert(req.mime_type.to_string()) { if let Some(offer) = self.offer.get() { - offer.client.event(offer.offer(req.mime_type)); + offer.send_offer(req.mime_type); } } Ok(()) diff --git a/src/ifs/zxdg_decoration_manager_v1.rs b/src/ifs/zxdg_decoration_manager_v1.rs index 0bc9c066..72ed06a5 100644 --- a/src/ifs/zxdg_decoration_manager_v1.rs +++ b/src/ifs/zxdg_decoration_manager_v1.rs @@ -72,7 +72,7 @@ impl ZxdgDecorationManagerV1 { let tl = self.client.lookup(req.toplevel)?; let obj = Rc::new(ZxdgToplevelDecorationV1::new(req.id, &self.client, &tl)); self.client.add_client_obj(&obj)?; - obj.send_configure(); + obj.do_send_configure(); Ok(()) } } diff --git a/src/ifs/zxdg_toplevel_decoration_v1.rs b/src/ifs/zxdg_toplevel_decoration_v1.rs index fef7b9e1..203cc4eb 100644 --- a/src/ifs/zxdg_toplevel_decoration_v1.rs +++ b/src/ifs/zxdg_toplevel_decoration_v1.rs @@ -1,5 +1,5 @@ -use crate::client::{Client, ClientError, DynEventFormatter}; +use crate::client::{Client, ClientError}; use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::{Decoration, XdgToplevel}; use crate::object::Object; use crate::utils::buffd::{MsgParser, MsgParserError}; @@ -30,20 +30,20 @@ impl ZxdgToplevelDecorationV1 { } } - fn configure(self: &Rc, mode: u32) -> DynEventFormatter { - Box::new(Configure { + fn send_configure(&self, mode: u32) { + self.client.event(Configure { self_id: self.id, mode, }) } - pub fn send_configure(self: &Rc) { + pub fn do_send_configure(&self) { let mode = match self.toplevel.decoration.get() { Decoration::Client => CLIENT_SIDE, Decoration::Server => SERVER_SIDE, }; - self.client.event(self.configure(mode)); - self.toplevel.xdg.send_configure(); + self.send_configure(mode); + self.toplevel.xdg.do_send_configure(); } fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> { @@ -54,13 +54,13 @@ impl ZxdgToplevelDecorationV1 { fn set_mode(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), SetModeError> { let _req: SetMode = self.client.parse(&**self, parser)?; - self.send_configure(); + self.do_send_configure(); Ok(()) } fn unset_mode(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), UnsetModeError> { let _req: UnsetMode = self.client.parse(&**self, parser)?; - self.send_configure(); + self.do_send_configure(); Ok(()) } } diff --git a/src/utils/buffd/buf_out.rs b/src/utils/buffd/buf_out.rs index 4f89824c..d833f3b0 100644 --- a/src/utils/buffd/buf_out.rs +++ b/src/utils/buffd/buf_out.rs @@ -1,10 +1,11 @@ -use crate::async_engine::AsyncFd; +use crate::async_engine::{AsyncFd, Timeout}; use crate::utils::buffd::{BufFdError, BUF_SIZE, CMSG_BUF_SIZE}; use futures::{select, FutureExt}; use std::collections::VecDeque; use std::mem::MaybeUninit; use std::rc::Rc; -use std::slice; +use std::{mem, slice}; +use futures::future::Fuse; use uapi::{c, Errno, OwnedFd}; pub(super) const OUT_BUF_SIZE: usize = 2 * BUF_SIZE; @@ -14,70 +15,114 @@ pub(super) struct MsgFds { pub(super) fds: Vec>, } +pub struct OutBuffer { + pub(super) read_pos: usize, + pub(super) write_pos: usize, + pub(super) buf: *mut [MaybeUninit; OUT_BUF_SIZE], + pub(super) fds: VecDeque, +} + +impl Default for OutBuffer { + fn default() -> Self { + Self { + read_pos: 0, + write_pos: 0, + buf: Box::into_raw(Box::new([MaybeUninit::::uninit(); OUT_BUF_SIZE / 4])) as _, + fds: Default::default(), + } + } +} + +impl OutBuffer { + pub fn write(&mut self, bytes: &[MaybeUninit]) { + if bytes.len() > OUT_BUF_SIZE - self.write_pos { + panic!("Out buffer overflow"); + } + unsafe { + (*self.buf)[self.write_pos..self.write_pos + bytes.len()].copy_from_slice(bytes); + } + self.write_pos += bytes.len(); + } + + pub fn is_full(&self) -> bool { + self.write_pos > BUF_SIZE + } + + pub fn len(&self) -> usize { + self.write_pos + } +} + +const LIMIT_PENDING: usize = 10; + +#[derive(Default)] +pub struct OutBufferSwapchain { + pub cur: OutBuffer, + pub pending: VecDeque, + pub free: Vec, +} + +impl OutBufferSwapchain { + pub fn exceeds_limit(&self) -> bool { + self.pending.len() > LIMIT_PENDING + } + + pub fn commit(&mut self) { + if self.cur.write_pos > 0 { + let new = self.free.pop().unwrap_or_else(|| { + log::warn!("new buffer"); + Default::default() + }); + let old = mem::replace(&mut self.cur, new); + self.pending.push_back(old); + } + } +} + pub struct BufFdOut { fd: AsyncFd, - - pub(super) out_pos: usize, - pub(super) out_buf: *mut [MaybeUninit; OUT_BUF_SIZE], - - pub(super) fds: VecDeque, - fd_ids: Vec, cmsg_buf: Box<[MaybeUninit; CMSG_BUF_SIZE]>, + fd_ids: Vec, } impl BufFdOut { pub fn new(fd: AsyncFd) -> Self { Self { fd, - out_pos: 0, - out_buf: Box::into_raw(Box::new([MaybeUninit::::uninit(); OUT_BUF_SIZE / 4])) as _, - fds: Default::default(), - fd_ids: vec![], cmsg_buf: Box::new([MaybeUninit::uninit(); CMSG_BUF_SIZE]), + fd_ids: vec![], } } - pub fn write(&mut self, bytes: &[MaybeUninit]) { - if bytes.len() > OUT_BUF_SIZE - self.out_pos { - panic!("Out buffer overflow"); - } - unsafe { - (*self.out_buf)[self.out_pos..self.out_pos + bytes.len()].copy_from_slice(bytes); - } - self.out_pos += bytes.len(); - } - - pub fn needs_flush(&self) -> bool { - self.out_pos > BUF_SIZE - } - - pub async fn flush(&mut self) -> Result<(), BufFdError> { - let mut timeout = None; - let mut pos = 0; - while pos < self.out_pos { - if self.flush_sync(&mut pos)? { + pub async fn flush(&mut self, buf: &mut OutBuffer, timeout: &mut Option>) -> Result<(), BufFdError> { + while buf.read_pos < buf.write_pos { + if self.flush_sync(buf)? { + self.fd.writable().await?; if timeout.is_none() { - timeout = Some(self.fd.eng().timeout(5000)?.fuse()); + *timeout = Some(self.fd.eng().timeout(5000)?.fuse()); } select! { - _ = timeout.as_mut().unwrap() => return Err(BufFdError::Timeout), + _ = timeout.as_mut().unwrap() => { + return Err(BufFdError::Timeout); + }, res = self.fd.writable().fuse() => res?, } } } - self.out_pos = 0; + buf.read_pos = 0; + buf.write_pos = 0; Ok(()) } - fn flush_sync(&mut self, pos: &mut usize) -> Result { - while *pos < self.out_pos { - let mut buf = unsafe { &(*self.out_buf)[*pos..self.out_pos] }; + fn flush_sync(&mut self, buffer: &mut OutBuffer) -> Result { + while buffer.read_pos < buffer.write_pos { + let mut buf = unsafe { &(*buffer.buf)[buffer.read_pos..buffer.write_pos] }; let mut cmsg_len = 0; let mut fds_opt = None; { - let mut f = self.fds.front().map(|f| f.pos); - if f == Some(*pos) { - let fds = self.fds.pop_front().unwrap(); + let mut f = buffer.fds.front().map(|f| f.pos); + if f == Some(buffer.read_pos) { + let fds = buffer.fds.pop_front().unwrap(); self.fd_ids.clear(); self.fd_ids.extend(fds.fds.iter().map(|f| f.raw())); let hdr = c::cmsghdr { @@ -88,10 +133,10 @@ impl BufFdOut { let mut cmsg_buf = &mut self.cmsg_buf[..]; cmsg_len = uapi::cmsg_write(&mut cmsg_buf, hdr, &self.fd_ids[..]).unwrap(); fds_opt = Some(fds); - f = self.fds.front().map(|f| f.pos) + f = buffer.fds.front().map(|f| f.pos) } if let Some(next_pos) = f { - buf = &buf[..next_pos - *pos]; + buf = &buf[..next_pos - buffer.read_pos]; } } let hdr = uapi::Msghdr { @@ -104,23 +149,23 @@ impl BufFdOut { Ok(b) => b, Err(Errno(c::EAGAIN)) => { if let Some(fds) = fds_opt { - self.fds.push_front(fds); + buffer.fds.push_front(fds); } return Ok(true); } Err(Errno(c::ECONNRESET)) => return Err(BufFdError::Closed), Err(e) => return Err(BufFdError::Io(e.into())), }; - *pos += bytes_sent; + buffer.read_pos += bytes_sent; } Ok(false) } } -impl Drop for BufFdOut { +impl Drop for OutBuffer { fn drop(&mut self) { unsafe { - Box::from_raw(self.out_buf as *mut [MaybeUninit; OUT_BUF_SIZE / 4]); + Box::from_raw(self.buf as *mut [MaybeUninit; OUT_BUF_SIZE / 4]); } } } diff --git a/src/utils/buffd/formatter.rs b/src/utils/buffd/formatter.rs index 25507814..13a958b5 100644 --- a/src/utils/buffd/formatter.rs +++ b/src/utils/buffd/formatter.rs @@ -1,21 +1,21 @@ use crate::fixed::Fixed; use crate::object::ObjectId; -use crate::utils::buffd::buf_out::{BufFdOut, MsgFds}; +use crate::utils::buffd::buf_out::{MsgFds, OutBuffer}; use std::mem; use std::mem::MaybeUninit; use std::rc::Rc; use uapi::OwnedFd; pub struct MsgFormatter<'a> { - buf: &'a mut BufFdOut, + buf: &'a mut OutBuffer, pos: usize, fds: &'a mut Vec>, } impl<'a> MsgFormatter<'a> { - pub fn new(buf: &'a mut BufFdOut, fds: &'a mut Vec>) -> Self { + pub fn new(buf: &'a mut OutBuffer, fds: &'a mut Vec>) -> Self { Self { - pos: buf.out_pos, + pos: buf.write_pos, buf, fds, } @@ -62,7 +62,7 @@ impl<'a> MsgFormatter<'a> { #[allow(dead_code)] pub fn array)>(&mut self, f: F) -> &mut Self { - let pos = self.buf.out_pos; + let pos = self.buf.write_pos; self.uint(0); let len = { let mut fmt = MsgFormatter { @@ -71,13 +71,13 @@ impl<'a> MsgFormatter<'a> { fds: self.fds, }; f(&mut fmt); - let len = self.buf.out_pos - pos - 4; + let len = self.buf.write_pos - pos - 4; let none = [MaybeUninit::new(0); 4]; - self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]); + self.buf.write(&none[..self.buf.write_pos.wrapping_neg() & 3]); len as u32 }; unsafe { - (*self.buf.out_buf)[pos..pos + 4].copy_from_slice(uapi::as_maybe_uninit_bytes(&len)); + (*self.buf.buf)[pos..pos + 4].copy_from_slice(uapi::as_maybe_uninit_bytes(&len)); } self } @@ -86,16 +86,16 @@ impl<'a> MsgFormatter<'a> { self.uint(mem::size_of_val(t) as u32); self.buf.write(uapi::as_maybe_uninit_bytes(t)); let none = [MaybeUninit::new(0); 4]; - self.buf.write(&none[..self.buf.out_pos.wrapping_neg() & 3]); + self.buf.write(&none[..self.buf.write_pos.wrapping_neg() & 3]); self } pub fn write_len(self) { - assert!(self.buf.out_pos - self.pos >= 8); + assert!(self.buf.write_pos - self.pos >= 8); assert_eq!(self.pos % 4, 0); unsafe { - let second_ptr = (self.buf.out_buf as *mut u8).add(self.pos + 4) as *mut u32; - let len = ((self.buf.out_pos - self.pos) as u32) << 16; + let second_ptr = (self.buf.buf as *mut u8).add(self.pos + 4) as *mut u32; + let len = ((self.buf.write_pos - self.pos) as u32) << 16; *second_ptr |= len; } if self.fds.len() > 0 { diff --git a/src/utils/buffd/mod.rs b/src/utils/buffd/mod.rs index 77ac83df..2d7df5c7 100644 --- a/src/utils/buffd/mod.rs +++ b/src/utils/buffd/mod.rs @@ -1,6 +1,6 @@ use crate::async_engine::AsyncError; pub use buf_in::BufFdIn; -pub use buf_out::BufFdOut; +pub use buf_out::{BufFdOut, OutBufferSwapchain}; pub use formatter::MsgFormatter; pub use parser::{MsgParser, MsgParserError}; use thiserror::Error; diff --git a/src/utils/queue.rs b/src/utils/queue.rs index 4c8be576..29456a5d 100644 --- a/src/utils/queue.rs +++ b/src/utils/queue.rs @@ -33,10 +33,6 @@ impl AsyncQueue { AsyncQueuePop { queue: self } } - pub fn size(&self) -> usize { - self.data.borrow().len() - } - pub fn clear(&self) { mem::take(&mut *self.data.borrow_mut()); }