Skip to content

Commit

Permalink
feat: optimize passive bluez message unmarshaller (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Aug 2, 2023
1 parent a7c87fb commit e0e87ec
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 15 deletions.
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ repos:
- id: debug-statements
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-json
- id: check-toml
- id: check-xml
Expand Down
1 change: 1 addition & 0 deletions bench/unmarshall_passive.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
unmarshaller.unmarshall()


count = 3000000
Expand Down
6 changes: 4 additions & 2 deletions src/dbus_fast/_private/unmarshaller.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,18 @@ cdef class Unmarshaller:
cdef unsigned int _body_len
cdef unsigned int _serial
cdef unsigned int _header_len
cdef object _message_type
cdef object _flag
cdef unsigned int _message_type
cdef unsigned int _flag
cdef unsigned int _msg_len
cdef unsigned int _is_native
cdef object _uint32_unpack
cdef object _int16_unpack
cdef object _uint16_unpack
cdef object _stream_reader
cdef object _sock_reader
cdef bint _negotiate_unix_fd
cdef bint _read_complete
cdef unsigned int _endian

cdef _next_message(self)

Expand Down
15 changes: 12 additions & 3 deletions src/dbus_fast/_private/unmarshaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,10 @@ class Unmarshaller:
"_uint16_unpack",
"_is_native",
"_stream_reader",
"_sock_reader",
"_negotiate_unix_fd",
"_read_complete",
"_endian",
)

def __init__(
Expand Down Expand Up @@ -236,6 +238,11 @@ def __init__(
if isinstance(stream, io.BufferedRWPair) and hasattr(stream, "reader"):
self._stream_reader = stream.reader.read # type: ignore[attr-defined]
self._stream_reader = stream.read
elif self._negotiate_unix_fd:
self._sock_reader = self._sock.recvmsg
else:
self._sock_reader = self._sock.recv
self._endian = 0

def _next_message(self) -> None:
"""Reset the unmarshaller to its initial state.
Expand Down Expand Up @@ -280,7 +287,7 @@ def _read_sock_with_fds(self, pos: _int, missing_bytes: _int) -> None:
# This will raise BlockingIOError if there is no data to read
# which we store in the MARSHALL_STREAM_END_ERROR object
try:
recv = self._sock.recvmsg(missing_bytes, UNIX_FDS_CMSG_LENGTH) # type: ignore[union-attr]
recv = self._sock_reader(missing_bytes, UNIX_FDS_CMSG_LENGTH) # type: ignore[union-attr]
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
Expand Down Expand Up @@ -311,7 +318,7 @@ def _read_sock_without_fds(self, pos: _int) -> None:
# which we store in the MARSHALL_STREAM_END_ERROR object
while True:
try:
data = self._sock.recv(DEFAULT_BUFFER_SIZE) # type: ignore[union-attr]
data = self._sock_reader(DEFAULT_BUFFER_SIZE) # type: ignore[union-attr]
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
Expand Down Expand Up @@ -650,7 +657,9 @@ def _read_header(self) -> None:
self._msg_len = (
self._header_len + (-self._header_len & 7) + self._body_len
) # align 8
self._readers = self._readers_by_type[endian]
if self._endian != endian:
self._readers = self._readers_by_type[endian]
self._endian = endian

def _read_body(self) -> None:
"""Read the body of the message."""
Expand Down
16 changes: 7 additions & 9 deletions src/dbus_fast/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,14 +435,12 @@ def __repr__(self) -> str:
)


@lru_cache(maxsize=None)
def get_signature_tree(signature: str) -> SignatureTree:
"""Get a signature tree for the given signature.
get_signature_tree = lru_cache(maxsize=None)(SignatureTree)
"""Get a signature tree for the given signature.
:param signature: The signature to get a tree for.
:type signature: str
:param signature: The signature to get a tree for.
:type signature: str
:returns: The signature tree for the given signature.
:rtype: :class:`SignatureTree`
"""
return SignatureTree(signature)
:returns: The signature tree for the given signature.
:rtype: :class:`SignatureTree`
"""

0 comments on commit e0e87ec

Please sign in to comment.