Skip to content

Commit

Permalink
feat: speed up constructing messages from the unmarshaller (#344)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Jan 7, 2025
1 parent c631151 commit b162494
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 30 deletions.
32 changes: 17 additions & 15 deletions src/dbus_fast/_private/unmarshaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,24 +750,26 @@ def _read_body(self) -> None:
flags = MESSAGE_FLAG_MAP.get(self._flag)
if flags is None:
flags = MESSAGE_FLAG_INTENUM(self._flag)
self._message = Message(
message_type=MESSAGE_TYPE_MAP[self._message_type],
flags=flags,
unix_fds=self._unix_fds,
signature=tree,
body=body,
serial=self._serial,
message = Message.__new__(Message)
message._fast_init(
header_fields[HEADER_DESTINATION_IDX],
header_fields[HEADER_PATH_IDX],
header_fields[HEADER_INTERFACE_IDX],
header_fields[HEADER_MEMBER_IDX],
MESSAGE_TYPE_MAP[self._message_type],
flags,
header_fields[HEADER_ERROR_NAME_IDX],
header_fields[HEADER_REPLY_SERIAL_IDX] or 0,
header_fields[HEADER_SENDER_IDX],
self._unix_fds,
tree,
body,
self._serial,
# The D-Bus implementation already validates the message,
# so we don't need to do it again.
validate=False,
destination=header_fields[HEADER_DESTINATION_IDX],
path=header_fields[HEADER_PATH_IDX],
interface=header_fields[HEADER_INTERFACE_IDX],
member=header_fields[HEADER_MEMBER_IDX],
reply_serial=header_fields[HEADER_REPLY_SERIAL_IDX],
error_name=header_fields[HEADER_ERROR_NAME_IDX],
sender=header_fields[HEADER_SENDER_IDX],
False,
)
self._message = message
self._read_complete = True

def unmarshall(self) -> Optional[Message]:
Expand Down
24 changes: 21 additions & 3 deletions src/dbus_fast/message.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,34 @@ cdef class Message:
cdef public object message_type
cdef public object flags
cdef public object error_name
cdef public object reply_serial
cdef public unsigned int reply_serial
cdef public object sender
cdef public cython.list unix_fds
cdef public list unix_fds
cdef public object signature
cdef public object signature_tree
cdef public object body
cdef public object serial
cdef public unsigned int serial

@cython.locals(
body_buffer=cython.bytearray,
header_buffer=cython.bytearray
)
cpdef _marshall(self, object negotiate_unix_fd)

cdef _fast_init(
self,
object destination,
object path,
object interface,
object member,
object message_type,
object flags,
object error_name,
unsigned int reply_serial,
object sender,
list unix_fds,
object signature_tree,
object body,
unsigned int serial,
bint validate
)
62 changes: 50 additions & 12 deletions src/dbus_fast/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
MESSAGE_TYPE_METHOD_CALL = MessageType.METHOD_CALL


_int = int
_str = str
_bool = bool
_MessageType = MessageType
_MessageFlag = MessageFlag
_list = list


class Message:
"""A class for sending and receiving messages through the
:class:`MessageBus <dbus_fast.message_bus.BaseMessageBus>` with the
Expand Down Expand Up @@ -114,27 +122,57 @@ def __init__(
body: list[Any] = [],
serial: Optional[int] = None,
validate: bool = True,
) -> None:
self._fast_init(
destination,
path,
interface,
member,
message_type,
flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags),
str(error_name.value) if type(error_name) is ErrorType else error_name,
reply_serial or 0,
sender,
unix_fds,
signature
if type(signature) is SignatureTree
else get_signature_tree(signature or ""),
body,
serial or 0,
validate,
)

def _fast_init(
self,
destination: Optional[_str],
path: Optional[_str],
interface: Optional[_str],
member: Optional[_str],
message_type: _MessageType,
flags: _MessageFlag,
error_name: Optional[_str],
reply_serial: _int,
sender: _str,
unix_fds: _list[int],
signature_tree: SignatureTree,
body: _list[Any],
serial: _int,
validate: _bool,
) -> None:
self.destination = destination
self.path = path
self.interface = interface
self.member = member
self.message_type = message_type
self.flags = flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags)
self.error_name = (
str(error_name.value) if type(error_name) is ErrorType else error_name
)
self.reply_serial = reply_serial or 0
self.flags = flags
self.error_name = error_name
self.reply_serial = reply_serial
self.sender = sender
self.unix_fds = unix_fds
if type(signature) is SignatureTree:
self.signature = signature.signature
self.signature_tree = signature
else:
self.signature = signature or "" # type: ignore[assignment]
self.signature_tree = get_signature_tree(signature or "")
self.signature = signature_tree.signature
self.signature_tree = signature_tree
self.body = body
self.serial = serial or 0
self.serial = serial

if not validate:
return
Expand Down

0 comments on commit b162494

Please sign in to comment.