Commit e0a5f356 authored by Alexandros Frantzis's avatar Alexandros Frantzis Committed by Alexandre Julliard

winewayland.drv: Remove wayland_surface destruction double locking.

Ignoring the possibility of HWND recycling allows us to use a simpler scheme to ensure valid access to the wayland_surface associated with an xdg_surface during event handling. The scheme involves setting HWND as the xdg_surface user data and using that to get to the wayland_surface. The prerequisite for this code to be correct is that the wayland surface destruction for a HWND must be performed under the wayland_win_data mutex.
parent 8fa02bf0
...@@ -33,38 +33,22 @@ ...@@ -33,38 +33,22 @@
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
/* Protects access to the user data of xdg_surface */
static pthread_mutex_t xdg_data_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct wayland_surface *wayland_surface_lock_xdg(struct xdg_surface *xdg_surface)
{
struct wayland_surface *surface;
pthread_mutex_lock(&xdg_data_mutex);
surface = xdg_surface_get_user_data(xdg_surface);
if (surface) pthread_mutex_lock(&surface->mutex);
pthread_mutex_unlock(&xdg_data_mutex);
return surface;
}
static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_surface, static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial) uint32_t serial)
{ {
struct wayland_surface *surface; struct wayland_surface *surface;
BOOL initial_configure = FALSE; BOOL initial_configure = FALSE;
HWND hwnd; HWND hwnd = data;
TRACE("serial=%u\n", serial); TRACE("serial=%u\n", serial);
if (!(surface = wayland_surface_lock_xdg(xdg_surface))) return; if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
/* Handle this event only if wayland_surface is still associated with /* Handle this event only if wayland_surface is still associated with
* the target xdg_surface. */ * the target xdg_surface. */
if (surface->xdg_surface == xdg_surface) if (surface->xdg_surface == xdg_surface)
{ {
initial_configure = surface->current_serial == 0; initial_configure = surface->current_serial == 0;
hwnd = surface->hwnd;
surface->current_serial = serial; surface->current_serial = serial;
xdg_surface_ack_configure(xdg_surface, serial); xdg_surface_ack_configure(xdg_surface, serial);
} }
...@@ -132,7 +116,6 @@ void wayland_surface_destroy(struct wayland_surface *surface) ...@@ -132,7 +116,6 @@ void wayland_surface_destroy(struct wayland_surface *surface)
} }
pthread_mutex_unlock(&process_wayland.pointer.mutex); pthread_mutex_unlock(&process_wayland.pointer.mutex);
pthread_mutex_lock(&xdg_data_mutex);
pthread_mutex_lock(&surface->mutex); pthread_mutex_lock(&surface->mutex);
if (surface->xdg_toplevel) if (surface->xdg_toplevel)
...@@ -143,7 +126,6 @@ void wayland_surface_destroy(struct wayland_surface *surface) ...@@ -143,7 +126,6 @@ void wayland_surface_destroy(struct wayland_surface *surface)
if (surface->xdg_surface) if (surface->xdg_surface)
{ {
xdg_surface_set_user_data(surface->xdg_surface, NULL);
xdg_surface_destroy(surface->xdg_surface); xdg_surface_destroy(surface->xdg_surface);
surface->xdg_surface = NULL; surface->xdg_surface = NULL;
} }
...@@ -155,7 +137,6 @@ void wayland_surface_destroy(struct wayland_surface *surface) ...@@ -155,7 +137,6 @@ void wayland_surface_destroy(struct wayland_surface *surface)
} }
pthread_mutex_unlock(&surface->mutex); pthread_mutex_unlock(&surface->mutex);
pthread_mutex_unlock(&xdg_data_mutex);
if (surface->latest_window_buffer) if (surface->latest_window_buffer)
wayland_shm_buffer_unref(surface->latest_window_buffer); wayland_shm_buffer_unref(surface->latest_window_buffer);
...@@ -179,7 +160,7 @@ void wayland_surface_make_toplevel(struct wayland_surface *surface) ...@@ -179,7 +160,7 @@ void wayland_surface_make_toplevel(struct wayland_surface *surface)
surface->xdg_surface = surface->xdg_surface =
xdg_wm_base_get_xdg_surface(process_wayland.xdg_wm_base, surface->wl_surface); xdg_wm_base_get_xdg_surface(process_wayland.xdg_wm_base, surface->wl_surface);
if (!surface->xdg_surface) goto err; if (!surface->xdg_surface) goto err;
xdg_surface_add_listener(surface->xdg_surface, &xdg_surface_listener, surface); xdg_surface_add_listener(surface->xdg_surface, &xdg_surface_listener, surface->hwnd);
surface->xdg_toplevel = xdg_surface_get_toplevel(surface->xdg_surface); surface->xdg_toplevel = xdg_surface_get_toplevel(surface->xdg_surface);
if (!surface->xdg_toplevel) goto err; if (!surface->xdg_toplevel) goto err;
......
...@@ -166,6 +166,7 @@ void wayland_surface_clear_role(struct wayland_surface *surface) DECLSPEC_HIDDEN ...@@ -166,6 +166,7 @@ void wayland_surface_clear_role(struct wayland_surface *surface) DECLSPEC_HIDDEN
void wayland_surface_attach_shm(struct wayland_surface *surface, void wayland_surface_attach_shm(struct wayland_surface *surface,
struct wayland_shm_buffer *shm_buffer, struct wayland_shm_buffer *shm_buffer,
HRGN surface_damage_region) DECLSPEC_HIDDEN; HRGN surface_damage_region) DECLSPEC_HIDDEN;
struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd) DECLSPEC_HIDDEN;
/********************************************************************** /**********************************************************************
* Wayland SHM buffer * Wayland SHM buffer
......
...@@ -338,3 +338,20 @@ void wayland_window_flush(HWND hwnd) ...@@ -338,3 +338,20 @@ void wayland_window_flush(HWND hwnd)
wayland_win_data_release(data); wayland_win_data_release(data);
} }
/**********************************************************************
* wayland_surface_lock_hwnd
*/
struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd)
{
struct wayland_win_data *data = wayland_win_data_get(hwnd);
struct wayland_surface *surface;
if (!data) return NULL;
if ((surface = data->wayland_surface)) pthread_mutex_lock(&surface->mutex);
wayland_win_data_release(data);
return surface;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment