Enums, bitfields and wl_arrays

Daniel Stone daniel at fooishbar.org
Thu Oct 8 13:13:21 PDT 2015


Hi,

On 5 October 2015 at 21:31, Victor Berger <victor.berger at m4x.org> wrote:
> Le 2015-10-05 21:53, Nils Chr. Brause a écrit :
>> Since a language binding should support unknown values anyway, I don't
>> quite
>> see the benefit of an 'open' flag.
>
> It depends. In some case, it could be valid to support unknown values by
> simply ignoring them.
>
> Consider a program written against a certain version of the protocol. Then,
> it is used on a compositor with a newer version of the protocol, where one
> of the enums have one more possible value.
>
> What can the client do if it receives this value ? It has no possible way to
> give it a proper meaning, so it can either ignore it, or trigger a fatal
> error. Are there other options ?
>
> In this case, for a "closed" enum, the binding can decide to ignore any
> value received on the wire that is not described in the XML, as anyway, the
> client would not know what to do with it (and if they knew, they should be
> using a more recent version of the binding).

This should never happen. The compositor is responsible for tracking
which version the client has bound, and not sending it values it
doesn't know what to do with.

I've heard mention that xdg-shell allows this, but I also can't see it
anywhere in the spec. Jasper?

> This can be useful in some languages to allow such a thing. For example in
> Rust, handling an "open" enum would require some overhead in terms of
> usability of the API, to gracefully handle unknown values. While simply
> ignoring them would lead to a much simpler design. Unless it is not a good
> idea to ignore unkown values, in which case I'd gladly read an explanation
> of why it is and which problems I missed.
>
> Without this flag, I have to choices: either consider enums as uints/ints
> and a set of constants to compare against (like C), of put this overhead on
> every single enum. To be honest, none of these possibilities feel
> satisfying. But They are still possible outcomes, hence the bindings _can_
> live without this indication.

My main concern was what I raised on IRC and Pekka in email:
> > There is a paradox: if the new attributes affect codegen for some
> > languages in a way that will break the build (which is exactly the
> > reason why they are wanted: to enforce type-safety), we cannot add
> > these attributes to the existing protocols, most importantly
> > wayland.xml, because it would "break existing code". You might escape
> > that paradox once, by claiming that there is no "existing code", after
> > all the generators for these languages will be new. But this escape
> > hatch will only work once. When these generators get into use, we can
> > no longer add the attributes to stable protocols without breaking
> > things. Not even if the generators had a "legacy mode" that ignores the
> > new attributes, because they would then regress on arguments that
> > already had the new attributes set.

The exact scenario being:
  - protocol v1 ships an enum with two possible values
  - protocol v2 adds another possible value for that enum
  - a client built against v1 will only ever speak v1 to the
compositor, but at runtime the library may support v2
  - a client built against v2 may also speak to a v1 compositor

For Rust, the answer here appears to be that the packages will all be
tightly bounded in versioning between build and runtime, so this
scenario is irrelevant.

For other bindings though, what happens here? Is ProtocolEnum
type-compatible, such that a client built against v1 bindings can pass
those values into a library which also supports v2? Does every bump
give you a new type, such that ProtocolEnumV1, ProtocolEnumV2, etc,
are all different types? If so, do you generate new call signatures
for every request/event which takes that enum?

This seems like it could get hairy. But if the answer from
Java/Haskell/etc is that the types are compatible, or there's some
other way to work around this such that it is possible to add new enum
values without breaking all existing users of rich bindings, then
great!

> I hope this was a clear explanation of why I think these values can be
> useful. Without then, I cannot really make use of the new attribute linking
> an argument to its enum, apart from writing it in the documentation and
> using (u)ints everywhere.

It has been very helpful, thanks.

Seems like, with this question resolved, we've finally arrived at a
conclusion here.

Cheers,
Daniel


More information about the wayland-devel mailing list