From 082d15de461ba645270bef2999099daa967e7ada Mon Sep 17 00:00:00 2001 From: Olivier Crete Date: Mon, 27 Apr 2015 13:36:49 -0400 Subject: [PATCH] wayland: Use private queue and free proxy Doing roundtrips from the main queue is unsafe as the application could be using it from another thread. Also free the registry proxy as it was previously leaked. --- src/i965_output_wayland.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/i965_output_wayland.c b/src/i965_output_wayland.c index 5a75397..489e41e 100644 --- a/src/i965_output_wayland.c +++ b/src/i965_output_wayland.c @@ -40,7 +40,9 @@ typedef uint32_t (*wl_display_get_global_func)(struct wl_display *display, const char *interface, uint32_t version); -typedef void (*wl_display_roundtrip_func)(struct wl_display *display); +typedef struct wl_event_queue *(*wl_display_create_queue_func)(struct wl_display *display); +typedef int (*wl_display_roundtrip_queue_func)(struct wl_display *display, struct wl_event_queue *queue); +typedef void (*wl_event_queue_destroy_func)(struct wl_event_queue *queue); typedef struct wl_proxy *(*wl_proxy_create_func)(struct wl_proxy *factory, const struct wl_interface *interface); @@ -48,22 +50,27 @@ typedef void (*wl_proxy_destroy_func)(struct wl_proxy *proxy); typedef void (*wl_proxy_marshal_func)(struct wl_proxy *p, uint32_t opcode, ...); typedef int (*wl_proxy_add_listener_func) (struct wl_proxy *proxy, void (**implementation)(void), void *data); +typedef void (*wl_proxy_set_queue_func)(struct wl_proxy *proxy, struct wl_event_queue *queue); struct wl_vtable { const struct wl_interface *buffer_interface; const struct wl_interface *drm_interface; const struct wl_interface *registry_interface; - wl_display_roundtrip_func display_roundtrip; + wl_display_create_queue_func display_create_queue; + wl_display_roundtrip_queue_func display_roundtrip_queue; + wl_event_queue_destroy_func event_queue_destroy; wl_proxy_create_func proxy_create; wl_proxy_destroy_func proxy_destroy; wl_proxy_marshal_func proxy_marshal; wl_proxy_add_listener_func proxy_add_listener; + wl_proxy_set_queue_func proxy_set_queue; }; struct va_wl_output { struct dso_handle *libegl_handle; struct dso_handle *libwl_client_handle; struct wl_vtable vtable; + struct wl_event_queue *queue; struct wl_drm *wl_drm; struct wl_registry *wl_registry; }; @@ -161,10 +168,14 @@ ensure_wl_output(VADriverContextP ctx) if (wl_output->wl_drm) return true; + wl_output->queue = wl_vtable->display_create_queue (ctx->native_dpy); + wl_output->wl_registry = display_get_registry(wl_vtable, ctx->native_dpy); + wl_vtable->proxy_set_queue ((struct wl_proxy *) wl_output->wl_registry, + wl_output->queue); registry_add_listener(wl_vtable, wl_output->wl_registry, ®istry_listener, ctx); - wl_vtable->display_roundtrip(ctx->native_dpy); + wl_vtable->display_roundtrip_queue(ctx->native_dpy, wl_output->queue); if (!wl_output->wl_drm) return false; return true; @@ -343,8 +354,12 @@ i965_output_wayland_init(VADriverContextP ctx) offsetof(struct wl_vtable, buffer_interface) }, { "wl_registry_interface", offsetof(struct wl_vtable, registry_interface) }, - { "wl_display_roundtrip", - offsetof(struct wl_vtable, display_roundtrip) }, + { "wl_display_create_queue", + offsetof(struct wl_vtable, display_create_queue) }, + { "wl_display_roundtrip_queue", + offsetof(struct wl_vtable, display_roundtrip_queue) }, + { "wl_event_queue_destroy", + offsetof(struct wl_vtable, event_queue_destroy) }, { "wl_proxy_create", offsetof(struct wl_vtable, proxy_create) }, { "wl_proxy_destroy", @@ -353,6 +368,8 @@ i965_output_wayland_init(VADriverContextP ctx) offsetof(struct wl_vtable, proxy_marshal) }, { "wl_proxy_add_listener", offsetof(struct wl_vtable, proxy_add_listener) }, + { "wl_proxy_set_queue", + offsetof(struct wl_vtable, proxy_set_queue) }, { NULL, } }; @@ -410,6 +427,16 @@ i965_output_wayland_terminate(VADriverContextP ctx) wl_output->wl_drm = NULL; } + if (wl_output->wl_registry) { + wl_output->vtable.proxy_destroy((struct wl_proxy *)wl_output->wl_registry); + wl_output->wl_registry = NULL; + } + + if (wl_output->queue) { + wl_output->vtable.event_queue_destroy(wl_output->queue); + wl_output->queue = NULL; + } + if (wl_output->libegl_handle) { dso_close(wl_output->libegl_handle); wl_output->libegl_handle = NULL; -- 1.9.1