diff --git a/jay-config/src/_private.rs b/jay-config/src/_private.rs index ba8d7d43..099d09d3 100644 --- a/jay-config/src/_private.rs +++ b/jay-config/src/_private.rs @@ -16,18 +16,20 @@ use { pub const VERSION: u32 = 1; -#[repr(C)] +pub type ServerHandler = unsafe fn(data: *const u8, msg: &ipc::ClientMessage<'_>); +pub type ConfigHandler = unsafe fn(data: *const u8, msg: &ipc::ServerMessage); +pub type Unref = unsafe fn(data: *const u8); + pub struct ConfigEntry { pub version: u32, - pub init: unsafe extern "C" fn( + pub init: unsafe fn( srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), - msg: *const u8, - size: usize, + srv_unref: Unref, + srv_handler: ServerHandler, + msg: ipc::InitMessage, ) -> *const u8, - pub unref: unsafe extern "C" fn(data: *const u8), - pub handle_msg: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), + pub unref: Unref, + pub handle_msg: ConfigHandler, } pub fn bincode_ops() -> impl Options { @@ -37,7 +39,7 @@ pub fn bincode_ops() -> impl Options { .with_no_limit() } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct WireMode { pub width: i32, pub height: i32, diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index 6610ad4d..82d19d8c 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -4,7 +4,7 @@ use { crate::{ _private::{ ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId, - WindowCriterionIpc, WindowCriterionStringField, WireMode, bincode_ops, + ServerHandler, Unref, WindowCriterionIpc, WindowCriterionStringField, WireMode, ipc::{ ClientMessage, InitMessage, Response, ServerFeature, ServerMessage, WorkspaceSource, }, @@ -38,7 +38,6 @@ use { workspace::WorkspaceDisplayOrder, xwayland::XScalingMode, }, - bincode::Options, futures_util::task::ArcWake, run_on_drop::{OnDrop, on_drop}, std::{ @@ -52,7 +51,6 @@ use { pin::Pin, ptr, rc::Rc, - slice, sync::{ Arc, Mutex, atomic::{AtomicBool, Ordering::Relaxed}, @@ -89,10 +87,10 @@ struct KeyHandler { } pub(crate) struct ConfigClient { - configure: extern "C" fn(), + configure: fn(), srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), + srv_unref: Unref, + srv_handler: ServerHandler, key_handlers: RefCell>, timer_handlers: RefCell>, response: RefCell>, @@ -109,7 +107,6 @@ pub(crate) struct ConfigClient { on_idle: RefCell>, on_switch_event: RefCell>>, on_unload: Cell>>>, - bufs: RefCell>>, reload: Cell, read_interests: RefCell>, write_interests: RefCell>, @@ -197,13 +194,12 @@ unsafe fn with_client T>(data: *const u8, f: F) - }) } -pub unsafe extern "C" fn init( +pub unsafe fn init( srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), - init: *const u8, - size: usize, - f: extern "C" fn(), + srv_unref: Unref, + srv_handler: ServerHandler, + init: InitMessage, + f: fn(), ) -> *const u8 { let client = Rc::new(ConfigClient { configure: f, @@ -226,7 +222,6 @@ pub unsafe extern "C" fn init( on_idle: Default::default(), on_switch_event: Default::default(), on_unload: Default::default(), - bufs: Default::default(), reload: Cell::new(false), read_interests: Default::default(), write_interests: Default::default(), @@ -239,22 +234,20 @@ pub unsafe extern "C" fn init( feat_mod_mask: Cell::new(false), feat_show_workspace_on: Cell::new(false), }); - let init = unsafe { slice::from_raw_parts(init, size) }; client.handle_init_msg(init); Rc::into_raw(client) as *const u8 } -pub unsafe extern "C" fn unref(data: *const u8) { +pub unsafe fn unref(data: *const u8) { let client = data as *const ConfigClient; unsafe { drop(Rc::from_raw(client)); } } -pub unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { +pub unsafe fn handle_msg(data: *const u8, msg: &ServerMessage) { unsafe { with_client(data, |client| { - let msg = slice::from_raw_parts(msg, size); client.handle_msg(msg); }); } @@ -284,13 +277,9 @@ enum GenericCriterion<'a, Crit, Matcher> { impl ConfigClient { fn send(&self, msg: &ClientMessage) { - let mut buf = self.bufs.borrow_mut().pop().unwrap_or_default(); - buf.clear(); - bincode_ops().serialize_into(&mut buf, msg).unwrap(); unsafe { - (self.srv_handler)(self.srv_data, buf.as_ptr(), buf.len()); + (self.srv_handler)(self.srv_data, msg); } - self.bufs.borrow_mut().push(buf); } fn send_with_response(&self, msg: &ClientMessage) -> Response { @@ -1609,6 +1598,7 @@ impl ConfigClient { } } + #[allow(dead_code)] pub fn log(&self, level: LogLevel, msg: &str, file: Option<&str>, line: Option) { self.send(&ClientMessage::Log { level, @@ -2032,7 +2022,7 @@ impl ConfigClient { self.send(&ClientMessage::SeatMoveTab { seat, right }); } - fn handle_msg(&self, msg: &[u8]) { + fn handle_msg(&self, msg: &ServerMessage) { self.handle_msg2(msg); self.dispatch_futures(); } @@ -2163,16 +2153,8 @@ impl ConfigClient { } } - fn handle_msg2(&self, msg: &[u8]) { - let res = bincode_ops().deserialize::(msg); - let msg = match res { - Ok(msg) => msg, - Err(e) => { - let msg = format!("could not deserialize message: {}", e); - self.log(LogLevel::Error, &msg, None, None); - return; - } - }; + fn handle_msg2(&self, msg: &ServerMessage) { + let msg = msg.clone(); match msg { ServerMessage::Configure { reload } => { self.reload.set(reload); @@ -2347,15 +2329,7 @@ impl ConfigClient { } } - fn handle_init_msg(&self, msg: &[u8]) { - let init = match bincode_ops().deserialize::(msg) { - Ok(m) => m, - Err(e) => { - let msg = format!("could not deserialize message: {}", e); - self.log(LogLevel::Error, &msg, None, None); - return; - } - }; + fn handle_init_msg(&self, init: InitMessage) { match init { InitMessage::V1(_) => {} } diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index d381f423..c3dfae74 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -24,7 +24,7 @@ use { std::time::{Duration, SystemTime}, }; -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq)] #[serde(transparent)] pub struct ServerFeature(u16); @@ -34,7 +34,7 @@ impl ServerFeature { pub const SHOW_WORKSPACE_ON: Self = Self(2); } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub enum ServerMessage { Configure { reload: bool, @@ -115,7 +115,7 @@ pub enum ServerMessage { }, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub enum ClientMessage<'a> { Reload, Quit, @@ -922,13 +922,13 @@ pub enum ClientMessage<'a> { }, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub enum WorkspaceSource { Seat(Seat), Explicit(Workspace), } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub enum Response { None, GetSeats { @@ -1178,10 +1178,10 @@ pub enum Response { }, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub enum InitMessage { V1(V1InitMessage), } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct V1InitMessage {} diff --git a/src/config.rs b/src/config.rs index 89cdfe5e..3c7c830f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,10 +15,9 @@ use { ptr_ext::PtrExt, }, }, - bincode::Options, jay_config::{ _private::{ - ConfigEntry, VERSION, bincode_ops, + ConfigEntry, VERSION, ipc::{InitMessage, ServerFeature, ServerMessage, V1InitMessage}, }, input::{InputDevice, Seat, SwitchEvent}, @@ -167,18 +166,17 @@ impl Drop for ConfigProxy { } } -unsafe extern "C" fn default_client_init( +unsafe fn default_client_init( srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), - msg: *const u8, - size: usize, + srv_unref: jay_config::_private::Unref, + srv_handler: jay_config::_private::ServerHandler, + msg: InitMessage, ) -> *const u8 { - extern "C" fn configure() { + fn configure() { jay_toml_config::configure(); } unsafe { - jay_config::_private::client::init(srv_data, srv_unref, srv_handler, msg, size, configure) + jay_config::_private::client::init(srv_data, srv_unref, srv_handler, msg, configure) } } @@ -194,7 +192,6 @@ impl ConfigProxy { state: state.clone(), next_id: NumCell::new(1), keymaps: Default::default(), - bufs: Default::default(), workspace_ids: NumCell::new(1), workspaces_by_name: Default::default(), workspaces_by_id: Default::default(), @@ -218,16 +215,13 @@ impl ConfigProxy { window_matcher_no_auto_focus: Default::default(), window_matcher_initial_tile_state: Default::default(), }); - let init_msg = bincode_ops() - .serialize(&InitMessage::V1(V1InitMessage {})) - .unwrap(); + let init_msg = InitMessage::V1(V1InitMessage {}); unsafe { let client_data = (entry.init)( Rc::into_raw(data.clone()) as _, unref, handle_msg, - init_msg.as_ptr(), - init_msg.len(), + init_msg, ); data.client_data.set(client_data); } @@ -259,21 +253,20 @@ impl ConfigProxy { } } -unsafe extern "C" fn unref(data: *const u8) { +unsafe fn unref(data: *const u8) { let server = data as *const ConfigProxyHandler; unsafe { drop(Rc::from_raw(server)); } } -unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { +unsafe fn handle_msg(data: *const u8, msg: &jay_config::_private::ipc::ClientMessage<'_>) { unsafe { let server = (data as *const ConfigProxyHandler).deref(); if server.dropped.get() { return; } let rc = Rc::from_raw(server); - let msg = std::slice::from_raw_parts(msg, size); rc.handle_request(msg); mem::forget(rc); } diff --git a/src/config/handler.rs b/src/config/handler.rs index 3cdb785e..412dca6e 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -37,15 +37,13 @@ use { errorfmt::ErrorFmt, numcell::NumCell, oserror::OsErrorExt, - stack::Stack, timer::{TimerError, TimerFd}, }, }, - bincode::Options, jay_config::{ _private::{ ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId, - WindowCriterionIpc, WindowCriterionStringField, WireMode, bincode_ops, + ConfigHandler, Unref, WindowCriterionIpc, WindowCriterionStringField, WireMode, ipc::{ClientMessage, Response, ServerMessage, WorkspaceSource}, }, Axis, Direction, Workspace, @@ -93,12 +91,11 @@ pub(super) struct ConfigProxyHandler { pub client_data: Cell<*const u8>, pub dropped: Cell, pub _version: u32, - pub unref: unsafe extern "C" fn(data: *const u8), - pub handle_msg: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), + pub unref: Unref, + pub handle_msg: ConfigHandler, pub state: Rc, pub next_id: NumCell, pub keymaps: CopyHashMap>, - pub bufs: Stack>, pub workspace_ids: NumCell, pub workspaces_by_name: CopyHashMap, u64>, @@ -202,13 +199,9 @@ impl ConfigProxyHandler { } pub fn send(&self, msg: &ServerMessage) { - let mut buf = self.bufs.pop().unwrap_or_default(); - buf.clear(); - bincode_ops().serialize_into(&mut buf, msg).unwrap(); unsafe { - (self.handle_msg)(self.client_data.get(), buf.as_ptr(), buf.len()); + (self.handle_msg)(self.client_data.get(), msg); } - self.bufs.push(buf); } pub fn respond(&self, msg: Response) { @@ -2813,17 +2806,14 @@ impl ConfigProxyHandler { Ok(()) } - pub fn handle_request(self: &Rc, msg: &[u8]) { + pub fn handle_request(self: &Rc, msg: &ClientMessage<'_>) { if let Err(e) = self.handle_request_(msg) { log::error!("Could not handle client request: {}", ErrorFmt(e)); } } - fn handle_request_(self: &Rc, msg: &[u8]) -> Result<(), CphError> { - let request = match bincode_ops().deserialize::(msg) { - Ok(msg) => msg, - Err(e) => return Err(CphError::ParsingFailed(e)), - }; + fn handle_request_(self: &Rc, request: &ClientMessage<'_>) -> Result<(), CphError> { + let request = request.clone(); match request { ClientMessage::Log { level, @@ -3599,8 +3589,6 @@ enum CphError { UnknownColor(u32), #[error("Sized element {0} is not known")] UnknownSized(u32), - #[error("Could not parse the message")] - ParsingFailed(#[source] bincode::Error), #[error("Could not process a `{0}` request")] FailedRequest(&'static str, #[source] Box), #[error(transparent)] diff --git a/src/it/test_config.rs b/src/it/test_config.rs index 56ee5272..2706ae58 100644 --- a/src/it/test_config.rs +++ b/src/it/test_config.rs @@ -6,11 +6,10 @@ use { tree::OutputNode, utils::{copyhashmap::CopyHashMap, stack::Stack}, }, - bincode::Options, isnt::std_1::primitive::IsntConstPtrExt, jay_config::{ _private::{ - ConfigEntry, VERSION, bincode_ops, + ConfigEntry, VERSION, ipc::{ClientMessage, Response, ServerMessage}, }, Axis, Direction, @@ -53,12 +52,11 @@ where res } -unsafe extern "C" fn init( +unsafe fn init( srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), - _msg: *const u8, - _size: usize, + srv_unref: jay_config::_private::Unref, + srv_handler: jay_config::_private::ServerHandler, + _msg: jay_config::_private::ipc::InitMessage, ) -> *const u8 { let tc = CONFIG.get(); assert!(tc.is_not_null()); @@ -76,23 +74,15 @@ unsafe extern "C" fn init( } } -unsafe extern "C" fn unref(data: *const u8) { +unsafe fn unref(data: *const u8) { unsafe { Rc::decrement_strong_count(data.cast::()); } } -unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { +unsafe fn handle_msg(data: *const u8, msg: &ServerMessage) { let tc = unsafe { &*data.cast::() }; - let msg = unsafe { std::slice::from_raw_parts(msg, size) }; - let res = bincode_ops().deserialize::(msg); - let msg = match res { - Ok(msg) => msg, - Err(e) => { - log::error!("could not deserialize message: {}", e); - return; - } - }; + let msg = msg.clone(); match msg { ServerMessage::Configure { .. } => {} ServerMessage::Response { response } => { @@ -138,8 +128,8 @@ unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) { #[derive(Copy, Clone)] struct ServerData { srv_data: *const u8, - srv_unref: unsafe extern "C" fn(data: *const u8), - srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), + srv_unref: jay_config::_private::Unref, + srv_handler: jay_config::_private::ServerHandler, } pub struct TestConfig { @@ -170,10 +160,8 @@ impl TestConfig { Some(srv) => srv, _ => bail!("srv not set"), }; - let mut buf = vec![]; - bincode_ops().serialize_into(&mut buf, msg).unwrap(); unsafe { - (srv.srv_handler)(srv.srv_data, buf.as_ptr(), buf.len()); + (srv.srv_handler)(srv.srv_data, msg); } Ok(()) }