Wayland generic dispatching API proposal version 2

Kristian Høgsberg hoegsberg at gmail.com
Tue Jan 15 10:50:26 PST 2013


On Mon, Jan 14, 2013 at 09:34:34PM -0600, Jason Ekstrand wrote:
> Wayland devs:
> A few weeks ago, I sent out a proposal on how we could extend the current
> Wayland API to allow for more general event and request dispatching.  I finally
> got around to talking to Kristian about it and some of the ABI issues and
> here's a second version of my proposal. I will also try and organize things a
> bit better.

This looks good, I think you're off in the right direction.

Kristian

> The core of the generic dispatching API would be a dispatcher function of the
> following type:
> 
> void wl_libffi_server_dispatcher(struct wl_object * reciever, uint32_t opcode,
>         void *client, void *resource, union wl_argument *args);
> 
> where wl_argument is given by the following union:
> 
> union wl_argument {
>     int32_t i;
>     uint32_t u;
>     wl_fixed_t f;
>     const char * s;
>     struct wl_object * o;
>     uint32_t n;
>     struct wl_array * a;
>     int32_t h;
> };
> 
> The exact meaning of the two void pointer arguments depends on whether the
> dispatcher is for client-side or server-side.  On the client side, the first is
> the void pointer given to the library by the client code and the second is the
> server-side object from which the event originates.  On the server side, the
> first is a pointer to the wl_client while the second is a pointer to the
> wl_resource.
> 
> In order to allow the use of these dispatchers, we would modify wl_interface
> and wl_object in the following way:
> 
> struct wl_interface {
>     const char *name;
>     unt32_t version;
>     int method_count;
>     const struct wl_message *methods;
>     int event_count;
>     const struct wl_message *events;
> 
>     /* Added in version 1 */
>     void (*dispatcher)(struct wl_object *, uint32_t, void *, void *,
>             union wl_argument *);
> };
> 
> struct wl_object {
>     const struct wl_interface *interface;
>     void *implementation;
>     uint32_t id;
> };
> 
> First note that I have only made 3 changes:
>  * version is now of type int32_t in wl_interface
>  * added dispatcher field to the end of wl_interface
>  * implementation is now of type void * in wl_object
> 
> There would then be a few changes to the semantics of wl_interface.
> Specifically, the version field would now come in two parts: an interface
> version and a struct version.  The bottom 16 bits would represent the interface
> version as before while the top 16 bits would represent a structure version
> with the original version of the structure being version 0.  In this way, code
> built against the original version of libwayland should not need any
> modification as it should already be setting the version number to something
> sufficiently low that the top 16 bits are zeros.  However, of code wishes to
> take advantage of the dispatcher field, it can set the top 16 bits to 1 to
> specify the next version of the structure.
> 
> When sending an request (or an event in the client case), libwayland will look
> at the structure version.  If the structure version is at least 1, it will look
> at the dispatcher.  If the structure version is zero or if the dispatcher is
> null, it will use the default dispatcher that uses libffi and attempt to call a
> function off the C function table provided in the implementation field.  If the
> structure version is at least one and the dispatcher is not null, then it will
> attempt to use the provided dispatcher.  If it uses an external dispatcher,
> then the implementation field in the wl_object is used by the external
> dispatcher in whatever way it pleases.
> 
> Concerning ABI: The only change that should change the layout or packing of any
> of the structures is the addition of the dispatcher field.  However, we only
> ever use pointers to wl_interface objects.  Because of this, even if the
> wl_interface object is created in client code that is using old header files,
> the dispatcher field should never get accessed as long as version is set
> reasonably.
> 
> Added functions: The second part of this proposal is to add a third version to
> each of our sets of variadic functions (such as wl_resource_post_event).  Each
> of our variadic functions comes in both a variadic form and one that takes a
> va_args argument.  We would add a third version that takes an argument of type
> union wl_argument * to allow for dynamic argument conversion.  These functions
> should be fairly simple and straightforward to implement.
> 
> There are a couple of specific advantages to adding custom dispatchers.  The
> first is that it makes it much easier to write language bindings for dynamic
> languages like Java or Python since you can do argument conversion in a dynamic
> way rather than having to auto-generate the argument conversion code.  If, for
> some reason, you wanted to be able to avoid libffi, it is easy to generate a
> dispatcher for a specific C interface.  For example, a dispatcher for
> wl_display might look something like this:
> 
> void
> wl_shm_pool_dispatcher(struct wl_object *object, uint32_t opcode, void *client,
>         void *resource, union wl_argument *args)
> {
>     wl_display_interface *impl;
>     impl = (wl_display_interface *)object->implementation;
>     switch(opcode) {
>     case 0:
>         (*impl->sync)(client, resource, args[0].n);
>         break;
>     case 1:
>         (*impl->get_registry)(client, resource, args[0].n);
>         break;
>     }
> }
> 
> Please forgive my probably incorrect function pointer casting and calling
> semantics.  I haven't tried to compile the above.  If you wanted to create a
> dispatcher for a specific implementation of an interface, it could be even
> simpler.  This provides at least the possibility of not having to depend on
> libffi.
> 
> As always, questions and comments are welcome!
> --Jason Ekstrand
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list