Untwisting the xkb protocol marshalling

Enrico Weigelt, metux IT consult info at metux.net
Fri Jul 26 14:54:15 UTC 2024


Hello friends,


as part of my endeavour cleaning up and simplifying the protocol
marshalling code (*1), I'm aiming to replace most of common stuff (eg.
size checking, byte-swapping, reply assembly) by a bunch of pretty
simple macros calls, which even look a bit declarative programming
(eg. stating `REQUEST_FIELD_CARD32(foo)` in a request handler tells
that field `foo` is CARD32, and the macro takes care of swapping if
necessary). Another key aspect is reducing the actual transmission
(WriteToClient() calls) to just one final macro call, which also takes
care of final fixups like computing total packet size, setting packet
type, etc. Besides making the code much easier to understand, this also
clears the road for potential future transports that aren't stream based
(maybe shmem, binder, virtio, etc, *3).

For most extensions this is pretty simple and straightforward: some
might need a bit of cleanup done before, but nothing spectacular.
(see the upper commits of my WIP branch -- *2)

Xkb is very different. It's a complex beast that really isn't easy to
understand. (Much of the complexity seems to date back to ancient times,
where maybe compilers couldn't trusted in things like scoped fields
and dynamic variables sized arrays. As these days are gone for decades
now, we can make use of those techniques.)

Therefore I've chosen to do the refactoring in small steps, which
(hopefully) are easy to digest. Unfortunately, the queue went pretty
long (32 commits) for a single MR, but this way IMHO much easier to
review and also prodiving good documentation what (and why) things
had been done for future generations.

Filed MR 1623:

https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1623

Amongst the many things done here is eg.

* using static struct initialization and declaring fields where needed
* using stack allocations for small buffers, so saving us from
   unnecessary heap allocations and better cache utilization, besides
   better readability and no risk of forgotten free().
* easier to understand producer-consumer relationships of values
   (eg. try not to pass incompletely filled reply structs to dozens of
   functions calls, where some of them only consume a few fields, or try
   to declare/init the reply structs as late as possible, in one shot)
* collect payload fragments in one reply buffer, that's written out in
   one shot along with the reply header - instead of arbitrary number of
   individual WriteToClient() calls across dozens of subroutines.

I known this is a long and complex queue, that will take it's time for
review. If it helps, I could split out some of the lower commits to a
separate MR and rebase this one later - let me know if that makes sense.


have fun,
--mtx


*1) https://gitlab.freedesktop.org/xorg/xserver/-/issues/1701
*2) https://gitlab.freedesktop.org/metux/xserver/-/commits/wip/swapping
*3) indeed one of the future projects on my 2do list ;-)
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info at metux.net -- +49-151-27565287


More information about the xorg-devel mailing list