aboutsummaryrefslogtreecommitdiffstats
path: root/src/wayland-client.h
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-11-14 21:29:06 -0800
committerKristian Høgsberg <krh@bitplanet.net>2013-11-15 20:49:36 -0800
commit853c24e6998f747150e4233cf41bfa8268964cc2 (patch)
treec9ae09bb76bb6b0e06695e95d1c39f9ee9d4b744 /src/wayland-client.h
parentprotocol: add sub-surfaces to the core (diff)
downloadwayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar.gz
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar.bz2
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar.lz
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar.xz
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.tar.zst
wayland-853c24e6998f747150e4233cf41bfa8268964cc2.zip
client: Introduce functions to allocate and marshal proxies atomically
The server requires clients to only allocate one ID ahead of the previously highest ID in order to keep the ID range tight. Failure to do so will make the server close the client connection. However, the way we allocate new IDs is racy. The generated code looks like: new_proxy = wl_proxy_create(...); wl_proxy_marshal(proxy, ... new_proxy, ...); If two threads do this at the same time, there's a chance that thread A will allocate a proxy, then get pre-empted by thread B which then allocates a proxy and then passes it to wl_proxy_marshal(). The ID for thread As proxy will be one higher that the currently highest ID, but the ID for thread Bs proxy will be two higher. But since thread B prempted thread A before it could send its new ID, B will send its new ID first, the server will see the ID from thread Bs proxy first, and will reject it. We fix this by introducing wl_proxy_marshal_constructor(). This function is identical to wl_proxy_marshal(), except that it will allocate a wl_proxy for NEW_ID arguments and send it, all under the display mutex. By introducing a new function, we maintain backwards compatibility with older code from the generator, and make sure that the new generated code has an explicit dependency on a new enough libwayland-client.so. A virtual Wayland merit badge goes to Kalle Vahlman, who tracked this down and analyzed the issue. Reported-by: Kalle Vahlman <kalle.vahlman@movial.com>
Diffstat (limited to 'src/wayland-client.h')
-rw-r--r--src/wayland-client.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 43ba3fc..2a32785 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -126,6 +126,14 @@ void wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode,
union wl_argument *args);
struct wl_proxy *wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface);
+struct wl_proxy *wl_proxy_marshal_constructor(struct wl_proxy *proxy,
+ uint32_t opcode,
+ const struct wl_interface *interface,
+ ...);
+struct wl_proxy *
+wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
+ uint32_t opcode, union wl_argument *args,
+ const struct wl_interface *interface);
void wl_proxy_destroy(struct wl_proxy *proxy);
int wl_proxy_add_listener(struct wl_proxy *proxy,