Sharing a single wl_display (client) by multiple toolkits

Pekka Paalanen ppaalanen at gmail.com
Tue Mar 26 11:25:12 UTC 2019


On Tue, 26 Mar 2019 10:56:04 +0000
"Victor Berger" <victor.berger at m4x.org> wrote:

> Hi,
> 
> I just want to provide some perspective on this issue, which has arisen quite early
> I started the Rust bindings.
> 
> 25 mars 2019 10:20 "Pekka Paalanen" <ppaalanen at gmail.com> a écrit:
> 
> > One idea is arguably a hack: the first word pointed to by a wl_proxy
> > userdata could be a magic value, that allows the toolkit to identify
> > its own userdata.  
> 
> This is actually pretty similar to how user-data is handled in wayland-rs : the user
> data mechanism is actually a typed API, which will refuse access to the user data
> (return Option::None) if either the requested type does not match the stored type
> or the user-data of the proxy is not threadsafe and access is requested from an other
> thread than the one that set it up.
> 
> This allows toolkits built on wayland-rs to relatively easily identify if an object
> belongs to them or not. Toolkits will mostly use private types as user data, meaning
> the risk of a proxy having the proper type as user data while still not belonging to
> you is zero.
> 
> A second layer of this issue also arose at the level of integration of wayland-rs with
> liwayland. wayland-rs tracks more state than libwayland to provide the additional
> safety guarantees that an idiomatic Rust API requires. When wayland-rs is used as a
> Rust implementation of the protocol, it just does it internally. When it is used as
> a wrapper around libwayland, it hijacks the user-data mechanism of libwayland to store
> its additional state, and expose its own typed user-data mechanism on top of that.
> 
> Wayland-rs thus needs to distinguish objects that were created by it from objects that
> were not. To achieve this, given it already uses its own dispatcher function, it simply
> stores a magic value in the "implementation" field of the proxy and the actual implementation
> along with the rest of its state in the user data. This magic value is a pointer to some
> static variable defined in wayland-rs. This allows the crate to distinguish its own objects
> from the ones from elsewhere, even other versions of itself (cargo occasionally links different
> versions of the same crate into a single binary, treating them as just two different crates).

Hi Victor,

that sounds a quite clever workaround for the shortcomings of
libwayland-client ABI. :-)

> I don't know how much of a "hack" this all is, but this has worked quite well in practice.

The problem is that there is no guarantee of what is stored in the
beginning of userdata when you share with an arbitary toolkit written
in e.g. C or C++. The value could be the same while the toolkits
differ, causing a false match. Another problem is that if the userdata
pointer is not NULL, you cannot be sure how many bytes were allocated,
so dereferencing that pointer is always going to be a gamble. Maybe
some toolkit even stores arbitrary values instead of pointers there.

Therefore relying on userdata magic *alone* will never be completely
safe. But if you use the implementation pointer (wl_proxy_get_listener)
to guarantee that your framework was the one who set up the userdata,
then it is safe, and the userdata becomes uninteresting even since the
primary problem is already solved.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20190326/41add6a1/attachment-0001.sig>


More information about the wayland-devel mailing list