1
0
Fork 0
forked from wry/wry

dbus: remove unused server-side object support

This commit is contained in:
kossLAN 2026-05-29 09:29:29 -04:00
parent 6489c2821c
commit 9e428510ca
No known key found for this signature in database
7 changed files with 15 additions and 487 deletions

View file

@ -2,10 +2,7 @@ pub use types::*;
use {
crate::{
async_engine::{AsyncEngine, SpawnedFuture},
dbus::{
property::{Get, GetReply},
types::{ObjectPath, Signature, Variant},
},
dbus::{property::GetReply, types::{ObjectPath, Signature, Variant}},
io_uring::{IoUring, IoUringError},
utils::{
buf::DynamicBuf,
@ -19,20 +16,15 @@ use {
vecstorage::VecStorage,
xrd::{XRD, xrd},
},
wire_dbus::{
org,
org::freedesktop::dbus::properties::{GetAll, GetAllReply, PropertiesChanged},
},
},
ahash::AHashMap,
std::{
borrow::{Borrow, Cow},
borrow::Cow,
cell::{Cell, RefCell},
fmt::{Debug, Display},
future::Future,
marker::PhantomData,
mem,
ops::Deref,
pin::Pin,
rc::Rc,
task::{Context, Poll, Waker},
@ -280,24 +272,6 @@ pub struct DbusSocket {
headers: RefCell<VecStorage<(u8, Variant<'static>)>>,
run_toplevel: Rc<RunToplevel>,
signal_handlers: RefCell<AHashMap<(&'static str, &'static str), InterfaceSignalHandlers>>,
objects: CopyHashMap<Cow<'static, str>, Rc<DbusObjectData>>,
}
#[derive(Hash, Eq, PartialEq)]
struct MemberHandlerOwnedKey {
key: MemberHandlerKey<'static>,
}
#[derive(Hash, Eq, PartialEq)]
struct MemberHandlerKey<'a> {
interface: &'a str,
member: &'a str,
}
impl<'a> Borrow<MemberHandlerKey<'a>> for MemberHandlerOwnedKey {
fn borrow(&self) -> &MemberHandlerKey<'a> {
&self.key
}
}
const TY_BYTE: u8 = b'y';
@ -337,20 +311,6 @@ const NO_AUTO_START: u8 = 0x2;
#[expect(dead_code)]
const ALLOW_INTERACTIVE_AUTHORIZATION: u8 = 0x4;
#[expect(dead_code)]
pub const DBUS_NAME_FLAG_ALLOW_REPLACEMENT: u32 = 0x1;
#[expect(dead_code)]
pub const DBUS_NAME_FLAG_REPLACE_EXISTING: u32 = 0x2;
pub const DBUS_NAME_FLAG_DO_NOT_QUEUE: u32 = 0x4;
pub const DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: u32 = 1;
#[expect(dead_code)]
pub const DBUS_REQUEST_NAME_REPLY_IN_QUEUE: u32 = 2;
#[expect(dead_code)]
pub const DBUS_REQUEST_NAME_REPLY_EXISTS: u32 = 3;
#[expect(dead_code)]
pub const DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: u32 = 4;
pub const BUS_DEST: &str = "org.freedesktop.DBus";
pub const BUS_PATH: &str = "/org/freedesktop/DBus";
@ -650,270 +610,6 @@ struct InterfaceSignalHandlers {
conditional: AHashMap<String, Rc<dyn SignalHandlerApi>>,
}
struct DbusObjectData {
path: Cow<'static, str>,
methods: CopyHashMap<MemberHandlerOwnedKey, Rc<dyn MethodHandlerApi>>,
properties: CopyHashMap<MemberHandlerOwnedKey, Rc<dyn PropertyHandlerApi>>,
}
pub struct DbusObject {
socket: Rc<DbusSocket>,
data: Rc<DbusObjectData>,
}
impl Drop for DbusObject {
fn drop(&mut self) {
self.socket.objects.remove(&self.data.path);
}
}
impl DbusObject {
pub fn add_method<T, F>(&self, handler: F)
where
T: MethodCall<'static>,
F: for<'a> Fn(T::Generic<'a>, PendingReply<T::Reply>) + 'static,
{
let rhd = Rc::new(MethodHandlerData {
handler,
_phantom: Default::default(),
});
let key = MemberHandlerOwnedKey {
key: MemberHandlerKey {
interface: T::INTERFACE,
member: T::MEMBER,
},
};
self.data.methods.set(key, rhd);
}
pub fn set_property<T>(&self, value: Variant<'static>)
where
T: Property + 'static,
{
self.emit_signal(&PropertiesChanged {
interface_name: T::INTERFACE.into(),
changed_properties: Cow::Borrowed(&[DictEntry {
key: T::PROPERTY.into(),
value: value.borrow(),
}]),
invalidated_properties: Default::default(),
});
let phd = Rc::new(PropertyHandlerData::<T> {
data: value,
_phantom: Default::default(),
});
let key = MemberHandlerOwnedKey {
key: MemberHandlerKey {
interface: T::INTERFACE,
member: T::PROPERTY,
},
};
self.data.properties.set(key, phd);
}
pub fn emit_signal<'a, T: Signal<'a>>(&self, signal: &T) {
self.socket.emit_signal(&self.data.path, signal);
}
pub fn path(&self) -> &str {
&self.data.path
}
}
trait PropertyHandlerApi {
fn interface(&self) -> &'static str;
fn member(&self) -> &'static str;
fn value<'a>(&'a self) -> Variant<'a>;
}
struct PropertyHandlerData<T> {
data: Variant<'static>,
_phantom: PhantomData<T>,
}
impl<T> PropertyHandlerApi for PropertyHandlerData<T>
where
T: Property,
{
fn interface(&self) -> &'static str {
T::INTERFACE
}
fn member(&self) -> &'static str {
T::PROPERTY
}
fn value<'a>(&'a self) -> Variant<'a> {
self.data.borrow()
}
}
pub struct PendingReply<T> {
reply_expected: bool,
socket: Rc<DbusSocket>,
destination: String,
serial: u32,
_phantom: PhantomData<T>,
}
impl<T> PendingReply<T> {
#[expect(dead_code)]
pub fn reply_expected(&self) -> bool {
self.reply_expected
}
pub fn err(&self, msg: &str) {
if self.reply_expected {
self.socket.send_error(&self.destination, self.serial, msg);
}
}
}
impl<T> PendingReply<T>
where
T: Message<'static>,
{
pub fn ok<'a>(&self, msg: &T::Generic<'a>) {
if self.reply_expected {
self.socket.send_reply(&self.destination, self.serial, msg);
}
}
#[expect(dead_code)]
pub fn complete<'a>(&self, res: Result<&T::Generic<'a>, &str>) {
match res {
Ok(m) => self.ok(m),
Err(e) => self.err(e),
}
}
}
trait MethodHandlerApi {
fn signature(&self) -> &'static str;
fn handle(
&self,
object: &DbusObjectData,
socket: &Rc<DbusSocket>,
dest: &str,
serial: u32,
reply_expected: bool,
parser: &mut Parser,
) -> Result<(), DbusError>;
}
struct MethodHandlerData<T, F> {
handler: F,
_phantom: PhantomData<T>,
}
impl<T, F> MethodHandlerApi for MethodHandlerData<T, F>
where
T: MethodCall<'static>,
F: for<'a> Fn(T::Generic<'a>, PendingReply<T::Reply>) + 'static,
{
fn signature(&self) -> &'static str {
T::SIGNATURE
}
fn handle<'a>(
&self,
_object: &DbusObjectData,
socket: &Rc<DbusSocket>,
dest: &str,
serial: u32,
reply_expected: bool,
parser: &mut Parser<'a>,
) -> Result<(), DbusError> {
let msg = T::Generic::<'a>::unmarshal(parser)?;
let pr = PendingReply {
reply_expected,
socket: socket.clone(),
destination: dest.to_string(),
serial,
_phantom: Default::default(),
};
(self.handler)(msg, pr);
Ok(())
}
}
struct PropertyGetHandlerProxy;
impl MethodHandlerApi for PropertyGetHandlerProxy {
fn signature(&self) -> &'static str {
Get::<u32>::SIGNATURE
}
fn handle<'a>(
&self,
object: &DbusObjectData,
socket: &Rc<DbusSocket>,
dest: &str,
serial: u32,
reply_expected: bool,
parser: &mut Parser<'a>,
) -> Result<(), DbusError> {
if !reply_expected {
return Ok(());
}
let msg = org::freedesktop::dbus::properties::Get::unmarshal(parser)?;
let key = MemberHandlerKey {
interface: msg.interface_name.deref(),
member: msg.property_name.deref(),
};
match object.properties.get(&key) {
Some(h) => socket.send_reply(
dest,
serial,
&org::freedesktop::dbus::properties::GetReply { value: h.value() },
),
_ => socket.send_error(dest, serial, "Property does not exist"),
};
Ok(())
}
}
struct PropertyGetAllHandlerProxy;
impl MethodHandlerApi for PropertyGetAllHandlerProxy {
fn signature(&self) -> &'static str {
GetAll::SIGNATURE
}
fn handle<'a>(
&self,
object: &DbusObjectData,
socket: &Rc<DbusSocket>,
dest: &str,
serial: u32,
reply_expected: bool,
parser: &mut Parser<'a>,
) -> Result<(), DbusError> {
if !reply_expected {
return Ok(());
}
let msg = GetAll::unmarshal(parser)?;
let all_props = object.properties.lock();
let mut props = vec![];
for property in all_props.values() {
if property.interface() == msg.interface_name {
props.push(DictEntry {
key: property.member().into(),
value: property.value(),
});
}
}
socket.send_reply(
dest,
serial,
&GetAllReply {
props: props.into(),
},
);
Ok(())
}
}
pub mod prelude {
pub use {
super::{

View file

@ -68,7 +68,6 @@ async fn connect(
headers: Default::default(),
run_toplevel: run_toplevel.clone(),
signal_handlers: Default::default(),
objects: Default::default(),
});
let skt = socket.clone();
socket.call(

View file

@ -6,16 +6,13 @@ use {
crate::{
dbus::{
CallError, DbusError, DbusSocket, Headers, MSG_ERROR, MSG_METHOD_CALL,
MSG_METHOD_RETURN, MSG_SIGNAL, MemberHandlerKey, Message, MethodHandlerApi,
NO_REPLY_EXPECTED, Parser, PropertyGetAllHandlerProxy, PropertyGetHandlerProxy,
MSG_METHOD_RETURN, MSG_SIGNAL, Parser,
},
utils::{
bitflags::BitflagsExt,
bufio::BufIoIncoming,
errorfmt::ErrorFmt,
ptr_ext::{MutPtrExt, PtrExt},
},
wire_dbus::org::freedesktop::dbus::properties::{Get, GetAll},
},
std::{cell::UnsafeCell, ops::Deref, rc::Rc},
};
@ -64,7 +61,6 @@ impl Incoming {
return Err(DbusError::InvalidEndianess);
}
let msg_ty = msg_buf[1];
let flags = msg_buf[2];
let protocol = msg_buf[3];
if protocol != 1 {
return Err(DbusError::InvalidProtocol);
@ -94,66 +90,12 @@ impl Incoming {
};
match msg_ty {
MSG_METHOD_CALL => {
let (sender, interface, member, path) = match (
&headers.sender,
&headers.interface,
&headers.member,
&headers.path,
) {
(Some(s), Some(i), Some(m), Some(p)) => (s, i, m, p),
let sender = match &headers.sender {
Some(s) => s,
_ => return Err(DbusError::MissingMethodCallHeaders),
};
if let Some(object) = self.socket.objects.get(path.deref()) {
let method_handler;
let handler: Option<&dyn MethodHandlerApi> =
if (interface.deref(), member.deref()) == (Get::INTERFACE, Get::MEMBER) {
Some(&PropertyGetHandlerProxy)
} else if (interface.deref(), member.deref())
== (GetAll::INTERFACE, GetAll::MEMBER)
{
Some(&PropertyGetAllHandlerProxy)
} else {
let key = MemberHandlerKey {
interface: interface.deref(),
member: member.deref(),
};
method_handler = object.methods.get(&key);
method_handler.as_deref()
};
if let Some(handler) = handler {
let sig = headers.signature.as_deref().unwrap_or("");
if sig != handler.signature() {
let msg = format!(
"Method call has an invalid signature: expected: {}, actual: {}",
handler.signature(),
sig,
);
self.socket.send_error(sender.deref(), serial, &msg);
} else {
let reply_expected = !flags.contains(NO_REPLY_EXPECTED);
if let Err(e) = handler.handle(
&object,
&self.socket,
sender,
serial,
reply_expected,
&mut parser,
) {
log::error!(
"{}: Could not handle method call: {}",
self.socket.bus_name,
ErrorFmt(e)
);
}
}
} else {
self.socket
.send_error(sender.deref(), serial, "Method does not exist");
}
} else {
self.socket
.send_error(sender.deref(), serial, "Object does not exist");
}
self.socket
.send_error(sender.deref(), serial, "Object does not exist");
}
MSG_METHOD_RETURN | MSG_ERROR => {
let serial = match headers.reply_serial {

View file

@ -1,13 +1,12 @@
use {
crate::{
dbus::{
AsyncProperty, AsyncReply, AsyncReplySlot, BUS_DEST, BUS_PATH, DbusError, DbusObject,
DbusObjectData, DbusSocket, DbusType, ErrorMessage, Formatter, HDR_DESTINATION,
HDR_ERROR_NAME, HDR_INTERFACE, HDR_MEMBER, HDR_PATH, HDR_REPLY_SERIAL, HDR_SIGNATURE,
HDR_UNIX_FDS, Headers, InterfaceSignalHandlers, MSG_ERROR, MSG_METHOD_CALL,
MSG_METHOD_RETURN, MSG_SIGNAL, Message, MethodCall, NO_REPLY_EXPECTED, Parser,
Property, Reply, ReplyHandler, Signal, SignalHandler, SignalHandlerApi,
SignalHandlerData,
AsyncProperty, AsyncReply, AsyncReplySlot, BUS_DEST, BUS_PATH, DbusError, DbusSocket,
DbusType, ErrorMessage, Formatter, HDR_DESTINATION, HDR_ERROR_NAME, HDR_INTERFACE,
HDR_MEMBER, HDR_PATH, HDR_REPLY_SERIAL, HDR_SIGNATURE, HDR_UNIX_FDS, Headers,
InterfaceSignalHandlers, MSG_ERROR, MSG_METHOD_CALL, Message,
MethodCall, NO_REPLY_EXPECTED, Parser, Property, Reply, ReplyHandler, Signal,
SignalHandler, SignalHandlerApi, SignalHandlerData,
property::Get,
types::{ObjectPath, Signature, Variant},
},
@ -15,8 +14,8 @@ use {
wire_dbus::org,
},
std::{
borrow::Cow, cell::Cell, collections::hash_map::Entry, fmt::Write, marker::PhantomData,
mem, ops::DerefMut, rc::Rc,
cell::Cell, collections::hash_map::Entry, fmt::Write, marker::PhantomData, mem,
ops::DerefMut, rc::Rc,
},
uapi::c,
};
@ -28,7 +27,6 @@ impl DbusSocket {
self.outgoing_.take();
self.reply_handlers.clear();
self.signal_handlers.borrow_mut().clear();
self.objects.clear();
}
pub(super) fn kill(self: &Rc<Self>) {
@ -134,28 +132,6 @@ impl DbusSocket {
}
}
pub fn add_object(
self: &Rc<Self>,
object: impl Into<Cow<'static, str>>,
) -> Result<DbusObject, DbusError> {
let object = object.into();
let data = Rc::new(DbusObjectData {
path: object.clone(),
methods: Default::default(),
properties: Default::default(),
});
match self.objects.lock().entry(object) {
Entry::Occupied(_) => Err(DbusError::AlreadyHandled),
Entry::Vacant(v) => {
v.insert(data.clone());
Ok(DbusObject {
socket: self.clone(),
data,
})
}
}
}
pub fn handle_signal<T, F>(
self: &Rc<Self>,
sender: Option<&str>,
@ -268,29 +244,12 @@ impl DbusSocket {
);
}
pub fn emit_signal<'a, T: Signal<'a>>(&self, path: &str, msg: &T) -> u32 {
let (msg, serial) = self.format_signal(path, msg);
self.bufio.send(msg);
serial
}
pub fn send_error(&self, destination: &str, reply_serial: u32, msg: &str) -> u32 {
let (msg, serial) = self.format_error(destination, reply_serial, msg);
self.bufio.send(msg);
serial
}
pub fn send_reply<'a, T: Message<'a>>(
&self,
destination: &str,
reply_serial: u32,
msg: &T,
) -> u32 {
let (msg, serial) = self.format_reply(destination, reply_serial, msg);
self.bufio.send(msg);
serial
}
fn send_call<'a, T: Message<'a>>(
&self,
path: &str,
@ -303,10 +262,6 @@ impl DbusSocket {
serial
}
fn format_signal<'a, T: Signal<'a>>(&self, path: &str, msg: &T) -> (BufIoMessage, u32) {
self.format_generic(MSG_SIGNAL, Some(path), None, None, 0, msg, None, true, true)
}
fn format_error(&self, destination: &str, reply_serial: u32, msg: &str) -> (BufIoMessage, u32) {
let em = ErrorMessage { msg: msg.into() };
self.format_generic(
@ -322,25 +277,6 @@ impl DbusSocket {
)
}
fn format_reply<'a, T: Message<'a>>(
&self,
destination: &str,
reply_serial: u32,
msg: &T,
) -> (BufIoMessage, u32) {
self.format_generic(
MSG_METHOD_RETURN,
None,
Some(reply_serial),
Some(destination),
0,
msg,
None,
true,
true,
)
}
fn format_call<'a, T: Message<'a>>(
&self,
path: &str,

View file

@ -501,31 +501,6 @@ impl<'a> Variant<'a> {
w.push(c);
}
pub fn borrow<'b>(&'b self) -> Variant<'b> {
match self {
Variant::U8(v) => Variant::U8(*v),
Variant::Bool(v) => Variant::Bool(*v),
Variant::I16(v) => Variant::I16(*v),
Variant::U16(v) => Variant::U16(*v),
Variant::I32(v) => Variant::I32(*v),
Variant::U32(v) => Variant::U32(*v),
Variant::I64(v) => Variant::I64(*v),
Variant::U64(v) => Variant::U64(*v),
Variant::F64(v) => Variant::F64(*v),
Variant::String(v) => Variant::String(v.deref().into()),
Variant::ObjectPath(v) => Variant::ObjectPath(ObjectPath(v.0.deref().into())),
Variant::Signature(v) => Variant::Signature(Signature(v.0.deref().into())),
Variant::Variant(v) => Variant::Variant(Box::new(v.deref().borrow())),
Variant::Fd(v) => Variant::Fd(v.clone()),
Variant::Array(t, v) => {
Variant::Array(t.clone(), v.iter().map(|v| v.borrow()).collect())
}
Variant::DictEntry(k, v) => {
Variant::DictEntry(Box::new(k.deref().borrow()), Box::new(v.deref().borrow()))
}
Variant::Struct(v) => Variant::Struct(v.iter().map(|v| v.borrow()).collect()),
}
}
}
unsafe impl<'a> DbusType<'a> for Variant<'a> {

View file

@ -1,16 +0,0 @@
fn Get(interface_name: string, property_name: string) {
value: variant,
}
# fn Set(interface_name: string, property_name: string, value: variant) {
# }
fn GetAll(interface_name: string) {
props: array(dict(string, variant)),
}
sig PropertiesChanged {
interface_name: string,
changed_properties: array(dict(string, variant)),
invalidated_properties: array(string),
}

View file

@ -7,7 +7,3 @@ fn AddMatch(rule: string) { }
fn RemoveMatch(rule: string) { }
fn UpdateActivationEnvironment(environment: array(dict(string, string))) { }
fn RequestName(name: string, flags: u32) {
rv: u32,
}