1
0
Fork 0
forked from wry/wry

config: remove bincode command bridge

This commit is contained in:
kossLAN 2026-05-29 18:05:41 -04:00
parent d8920ed7a0
commit 87de5fcca3
No known key found for this signature in database
6 changed files with 64 additions and 119 deletions

View file

@ -16,18 +16,20 @@ use {
pub const VERSION: u32 = 1; 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 struct ConfigEntry {
pub version: u32, pub version: u32,
pub init: unsafe extern "C" fn( pub init: unsafe fn(
srv_data: *const u8, srv_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: ServerHandler,
msg: *const u8, msg: ipc::InitMessage,
size: usize,
) -> *const u8, ) -> *const u8,
pub unref: unsafe extern "C" fn(data: *const u8), pub unref: Unref,
pub handle_msg: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), pub handle_msg: ConfigHandler,
} }
pub fn bincode_ops() -> impl Options { pub fn bincode_ops() -> impl Options {
@ -37,7 +39,7 @@ pub fn bincode_ops() -> impl Options {
.with_no_limit() .with_no_limit()
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct WireMode { pub struct WireMode {
pub width: i32, pub width: i32,
pub height: i32, pub height: i32,

View file

@ -4,7 +4,7 @@ use {
crate::{ crate::{
_private::{ _private::{
ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId, ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId,
WindowCriterionIpc, WindowCriterionStringField, WireMode, bincode_ops, ServerHandler, Unref, WindowCriterionIpc, WindowCriterionStringField, WireMode,
ipc::{ ipc::{
ClientMessage, InitMessage, Response, ServerFeature, ServerMessage, WorkspaceSource, ClientMessage, InitMessage, Response, ServerFeature, ServerMessage, WorkspaceSource,
}, },
@ -38,7 +38,6 @@ use {
workspace::WorkspaceDisplayOrder, workspace::WorkspaceDisplayOrder,
xwayland::XScalingMode, xwayland::XScalingMode,
}, },
bincode::Options,
futures_util::task::ArcWake, futures_util::task::ArcWake,
run_on_drop::{OnDrop, on_drop}, run_on_drop::{OnDrop, on_drop},
std::{ std::{
@ -52,7 +51,6 @@ use {
pin::Pin, pin::Pin,
ptr, ptr,
rc::Rc, rc::Rc,
slice,
sync::{ sync::{
Arc, Mutex, Arc, Mutex,
atomic::{AtomicBool, Ordering::Relaxed}, atomic::{AtomicBool, Ordering::Relaxed},
@ -89,10 +87,10 @@ struct KeyHandler {
} }
pub(crate) struct ConfigClient { pub(crate) struct ConfigClient {
configure: extern "C" fn(), configure: fn(),
srv_data: *const u8, srv_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: ServerHandler,
key_handlers: RefCell<HashMap<(Seat, ModifiedKeySym), KeyHandler>>, key_handlers: RefCell<HashMap<(Seat, ModifiedKeySym), KeyHandler>>,
timer_handlers: RefCell<HashMap<Timer, Callback>>, timer_handlers: RefCell<HashMap<Timer, Callback>>,
response: RefCell<Vec<Response>>, response: RefCell<Vec<Response>>,
@ -109,7 +107,6 @@ pub(crate) struct ConfigClient {
on_idle: RefCell<Option<Callback>>, on_idle: RefCell<Option<Callback>>,
on_switch_event: RefCell<HashMap<InputDevice, Callback<SwitchEvent>>>, on_switch_event: RefCell<HashMap<InputDevice, Callback<SwitchEvent>>>,
on_unload: Cell<Option<OnDrop<Box<dyn FnOnce()>>>>, on_unload: Cell<Option<OnDrop<Box<dyn FnOnce()>>>>,
bufs: RefCell<Vec<Vec<u8>>>,
reload: Cell<bool>, reload: Cell<bool>,
read_interests: RefCell<HashMap<PollableId, Interest>>, read_interests: RefCell<HashMap<PollableId, Interest>>,
write_interests: RefCell<HashMap<PollableId, Interest>>, write_interests: RefCell<HashMap<PollableId, Interest>>,
@ -197,13 +194,12 @@ unsafe fn with_client<T, F: FnOnce(&ConfigClient) -> T>(data: *const u8, f: F) -
}) })
} }
pub unsafe extern "C" fn init( pub unsafe fn init(
srv_data: *const u8, srv_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: ServerHandler,
init: *const u8, init: InitMessage,
size: usize, f: fn(),
f: extern "C" fn(),
) -> *const u8 { ) -> *const u8 {
let client = Rc::new(ConfigClient { let client = Rc::new(ConfigClient {
configure: f, configure: f,
@ -226,7 +222,6 @@ pub unsafe extern "C" fn init(
on_idle: Default::default(), on_idle: Default::default(),
on_switch_event: Default::default(), on_switch_event: Default::default(),
on_unload: Default::default(), on_unload: Default::default(),
bufs: Default::default(),
reload: Cell::new(false), reload: Cell::new(false),
read_interests: Default::default(), read_interests: Default::default(),
write_interests: Default::default(), write_interests: Default::default(),
@ -239,22 +234,20 @@ pub unsafe extern "C" fn init(
feat_mod_mask: Cell::new(false), feat_mod_mask: Cell::new(false),
feat_show_workspace_on: Cell::new(false), feat_show_workspace_on: Cell::new(false),
}); });
let init = unsafe { slice::from_raw_parts(init, size) };
client.handle_init_msg(init); client.handle_init_msg(init);
Rc::into_raw(client) as *const u8 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; let client = data as *const ConfigClient;
unsafe { unsafe {
drop(Rc::from_raw(client)); 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 { unsafe {
with_client(data, |client| { with_client(data, |client| {
let msg = slice::from_raw_parts(msg, size);
client.handle_msg(msg); client.handle_msg(msg);
}); });
} }
@ -284,13 +277,9 @@ enum GenericCriterion<'a, Crit, Matcher> {
impl ConfigClient { impl ConfigClient {
fn send(&self, msg: &ClientMessage) { 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 { 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 { 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<u32>) { pub fn log(&self, level: LogLevel, msg: &str, file: Option<&str>, line: Option<u32>) {
self.send(&ClientMessage::Log { self.send(&ClientMessage::Log {
level, level,
@ -2032,7 +2022,7 @@ impl ConfigClient {
self.send(&ClientMessage::SeatMoveTab { seat, right }); self.send(&ClientMessage::SeatMoveTab { seat, right });
} }
fn handle_msg(&self, msg: &[u8]) { fn handle_msg(&self, msg: &ServerMessage) {
self.handle_msg2(msg); self.handle_msg2(msg);
self.dispatch_futures(); self.dispatch_futures();
} }
@ -2163,16 +2153,8 @@ impl ConfigClient {
} }
} }
fn handle_msg2(&self, msg: &[u8]) { fn handle_msg2(&self, msg: &ServerMessage) {
let res = bincode_ops().deserialize::<ServerMessage>(msg); let msg = msg.clone();
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;
}
};
match msg { match msg {
ServerMessage::Configure { reload } => { ServerMessage::Configure { reload } => {
self.reload.set(reload); self.reload.set(reload);
@ -2347,15 +2329,7 @@ impl ConfigClient {
} }
} }
fn handle_init_msg(&self, msg: &[u8]) { fn handle_init_msg(&self, init: InitMessage) {
let init = match bincode_ops().deserialize::<InitMessage>(msg) {
Ok(m) => m,
Err(e) => {
let msg = format!("could not deserialize message: {}", e);
self.log(LogLevel::Error, &msg, None, None);
return;
}
};
match init { match init {
InitMessage::V1(_) => {} InitMessage::V1(_) => {}
} }

View file

@ -24,7 +24,7 @@ use {
std::time::{Duration, SystemTime}, std::time::{Duration, SystemTime},
}; };
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] #[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq)]
#[serde(transparent)] #[serde(transparent)]
pub struct ServerFeature(u16); pub struct ServerFeature(u16);
@ -34,7 +34,7 @@ impl ServerFeature {
pub const SHOW_WORKSPACE_ON: Self = Self(2); pub const SHOW_WORKSPACE_ON: Self = Self(2);
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ServerMessage { pub enum ServerMessage {
Configure { Configure {
reload: bool, reload: bool,
@ -115,7 +115,7 @@ pub enum ServerMessage {
}, },
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ClientMessage<'a> { pub enum ClientMessage<'a> {
Reload, Reload,
Quit, Quit,
@ -922,13 +922,13 @@ pub enum ClientMessage<'a> {
}, },
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum WorkspaceSource { pub enum WorkspaceSource {
Seat(Seat), Seat(Seat),
Explicit(Workspace), Explicit(Workspace),
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Response { pub enum Response {
None, None,
GetSeats { GetSeats {
@ -1178,10 +1178,10 @@ pub enum Response {
}, },
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum InitMessage { pub enum InitMessage {
V1(V1InitMessage), V1(V1InitMessage),
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct V1InitMessage {} pub struct V1InitMessage {}

View file

@ -15,10 +15,9 @@ use {
ptr_ext::PtrExt, ptr_ext::PtrExt,
}, },
}, },
bincode::Options,
jay_config::{ jay_config::{
_private::{ _private::{
ConfigEntry, VERSION, bincode_ops, ConfigEntry, VERSION,
ipc::{InitMessage, ServerFeature, ServerMessage, V1InitMessage}, ipc::{InitMessage, ServerFeature, ServerMessage, V1InitMessage},
}, },
input::{InputDevice, Seat, SwitchEvent}, 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_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: jay_config::_private::Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: jay_config::_private::ServerHandler,
msg: *const u8, msg: InitMessage,
size: usize,
) -> *const u8 { ) -> *const u8 {
extern "C" fn configure() { fn configure() {
jay_toml_config::configure(); jay_toml_config::configure();
} }
unsafe { 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(), state: state.clone(),
next_id: NumCell::new(1), next_id: NumCell::new(1),
keymaps: Default::default(), keymaps: Default::default(),
bufs: Default::default(),
workspace_ids: NumCell::new(1), workspace_ids: NumCell::new(1),
workspaces_by_name: Default::default(), workspaces_by_name: Default::default(),
workspaces_by_id: Default::default(), workspaces_by_id: Default::default(),
@ -218,16 +215,13 @@ impl ConfigProxy {
window_matcher_no_auto_focus: Default::default(), window_matcher_no_auto_focus: Default::default(),
window_matcher_initial_tile_state: Default::default(), window_matcher_initial_tile_state: Default::default(),
}); });
let init_msg = bincode_ops() let init_msg = InitMessage::V1(V1InitMessage {});
.serialize(&InitMessage::V1(V1InitMessage {}))
.unwrap();
unsafe { unsafe {
let client_data = (entry.init)( let client_data = (entry.init)(
Rc::into_raw(data.clone()) as _, Rc::into_raw(data.clone()) as _,
unref, unref,
handle_msg, handle_msg,
init_msg.as_ptr(), init_msg,
init_msg.len(),
); );
data.client_data.set(client_data); 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; let server = data as *const ConfigProxyHandler;
unsafe { unsafe {
drop(Rc::from_raw(server)); 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 { unsafe {
let server = (data as *const ConfigProxyHandler).deref(); let server = (data as *const ConfigProxyHandler).deref();
if server.dropped.get() { if server.dropped.get() {
return; return;
} }
let rc = Rc::from_raw(server); let rc = Rc::from_raw(server);
let msg = std::slice::from_raw_parts(msg, size);
rc.handle_request(msg); rc.handle_request(msg);
mem::forget(rc); mem::forget(rc);
} }

View file

@ -37,15 +37,13 @@ use {
errorfmt::ErrorFmt, errorfmt::ErrorFmt,
numcell::NumCell, numcell::NumCell,
oserror::OsErrorExt, oserror::OsErrorExt,
stack::Stack,
timer::{TimerError, TimerFd}, timer::{TimerError, TimerFd},
}, },
}, },
bincode::Options,
jay_config::{ jay_config::{
_private::{ _private::{
ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId, ClientCriterionIpc, ClientCriterionStringField, GenericCriterionIpc, PollableId,
WindowCriterionIpc, WindowCriterionStringField, WireMode, bincode_ops, ConfigHandler, Unref, WindowCriterionIpc, WindowCriterionStringField, WireMode,
ipc::{ClientMessage, Response, ServerMessage, WorkspaceSource}, ipc::{ClientMessage, Response, ServerMessage, WorkspaceSource},
}, },
Axis, Direction, Workspace, Axis, Direction, Workspace,
@ -93,12 +91,11 @@ pub(super) struct ConfigProxyHandler {
pub client_data: Cell<*const u8>, pub client_data: Cell<*const u8>,
pub dropped: Cell<bool>, pub dropped: Cell<bool>,
pub _version: u32, pub _version: u32,
pub unref: unsafe extern "C" fn(data: *const u8), pub unref: Unref,
pub handle_msg: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), pub handle_msg: ConfigHandler,
pub state: Rc<State>, pub state: Rc<State>,
pub next_id: NumCell<u64>, pub next_id: NumCell<u64>,
pub keymaps: CopyHashMap<Keymap, Rc<KbvmMap>>, pub keymaps: CopyHashMap<Keymap, Rc<KbvmMap>>,
pub bufs: Stack<Vec<u8>>,
pub workspace_ids: NumCell<u64>, pub workspace_ids: NumCell<u64>,
pub workspaces_by_name: CopyHashMap<Rc<String>, u64>, pub workspaces_by_name: CopyHashMap<Rc<String>, u64>,
@ -202,13 +199,9 @@ impl ConfigProxyHandler {
} }
pub fn send(&self, msg: &ServerMessage) { 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 { 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) { pub fn respond(&self, msg: Response) {
@ -2813,17 +2806,14 @@ impl ConfigProxyHandler {
Ok(()) Ok(())
} }
pub fn handle_request(self: &Rc<Self>, msg: &[u8]) { pub fn handle_request(self: &Rc<Self>, msg: &ClientMessage<'_>) {
if let Err(e) = self.handle_request_(msg) { if let Err(e) = self.handle_request_(msg) {
log::error!("Could not handle client request: {}", ErrorFmt(e)); log::error!("Could not handle client request: {}", ErrorFmt(e));
} }
} }
fn handle_request_(self: &Rc<Self>, msg: &[u8]) -> Result<(), CphError> { fn handle_request_(self: &Rc<Self>, request: &ClientMessage<'_>) -> Result<(), CphError> {
let request = match bincode_ops().deserialize::<ClientMessage>(msg) { let request = request.clone();
Ok(msg) => msg,
Err(e) => return Err(CphError::ParsingFailed(e)),
};
match request { match request {
ClientMessage::Log { ClientMessage::Log {
level, level,
@ -3599,8 +3589,6 @@ enum CphError {
UnknownColor(u32), UnknownColor(u32),
#[error("Sized element {0} is not known")] #[error("Sized element {0} is not known")]
UnknownSized(u32), UnknownSized(u32),
#[error("Could not parse the message")]
ParsingFailed(#[source] bincode::Error),
#[error("Could not process a `{0}` request")] #[error("Could not process a `{0}` request")]
FailedRequest(&'static str, #[source] Box<Self>), FailedRequest(&'static str, #[source] Box<Self>),
#[error(transparent)] #[error(transparent)]

View file

@ -6,11 +6,10 @@ use {
tree::OutputNode, tree::OutputNode,
utils::{copyhashmap::CopyHashMap, stack::Stack}, utils::{copyhashmap::CopyHashMap, stack::Stack},
}, },
bincode::Options,
isnt::std_1::primitive::IsntConstPtrExt, isnt::std_1::primitive::IsntConstPtrExt,
jay_config::{ jay_config::{
_private::{ _private::{
ConfigEntry, VERSION, bincode_ops, ConfigEntry, VERSION,
ipc::{ClientMessage, Response, ServerMessage}, ipc::{ClientMessage, Response, ServerMessage},
}, },
Axis, Direction, Axis, Direction,
@ -53,12 +52,11 @@ where
res res
} }
unsafe extern "C" fn init( unsafe fn init(
srv_data: *const u8, srv_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: jay_config::_private::Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: jay_config::_private::ServerHandler,
_msg: *const u8, _msg: jay_config::_private::ipc::InitMessage,
_size: usize,
) -> *const u8 { ) -> *const u8 {
let tc = CONFIG.get(); let tc = CONFIG.get();
assert!(tc.is_not_null()); 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 { unsafe {
Rc::decrement_strong_count(data.cast::<TestConfig>()); Rc::decrement_strong_count(data.cast::<TestConfig>());
} }
} }
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::<TestConfig>() }; let tc = unsafe { &*data.cast::<TestConfig>() };
let msg = unsafe { std::slice::from_raw_parts(msg, size) }; let msg = msg.clone();
let res = bincode_ops().deserialize::<ServerMessage>(msg);
let msg = match res {
Ok(msg) => msg,
Err(e) => {
log::error!("could not deserialize message: {}", e);
return;
}
};
match msg { match msg {
ServerMessage::Configure { .. } => {} ServerMessage::Configure { .. } => {}
ServerMessage::Response { response } => { ServerMessage::Response { response } => {
@ -138,8 +128,8 @@ unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct ServerData { struct ServerData {
srv_data: *const u8, srv_data: *const u8,
srv_unref: unsafe extern "C" fn(data: *const u8), srv_unref: jay_config::_private::Unref,
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize), srv_handler: jay_config::_private::ServerHandler,
} }
pub struct TestConfig { pub struct TestConfig {
@ -170,10 +160,8 @@ impl TestConfig {
Some(srv) => srv, Some(srv) => srv,
_ => bail!("srv not set"), _ => bail!("srv not set"),
}; };
let mut buf = vec![];
bincode_ops().serialize_into(&mut buf, msg).unwrap();
unsafe { unsafe {
(srv.srv_handler)(srv.srv_data, buf.as_ptr(), buf.len()); (srv.srv_handler)(srv.srv_data, msg);
} }
Ok(()) Ok(())
} }