wlserver: Add naive locking to try to see if that fixes hangs for good.

Change the wl event loop to busy-wait for now as that's easiest to make
unlock periodically.
This commit is contained in:
Pierre-Loup A. Griffais 2019-12-31 10:50:22 +09:00
parent a537a04b10
commit 24c10095e5
3 changed files with 37 additions and 1 deletions

View file

@ -1416,6 +1416,8 @@ static void
handle_wl_surface_id(Display *dpy, win *w, long surfaceID)
{
struct wlr_surface *surface = NULL;
wlserver_lock();
struct wl_resource *resource = wl_client_get_object(wlserver.wlr.xwayland->client, surfaceID);
if (resource) {
@ -1424,14 +1426,18 @@ handle_wl_surface_id(Display *dpy, win *w, long surfaceID)
else
{
fprintf (stderr, "wayland surface for window not found, implement pending list for late surface notification\n");
wlserver_unlock();
return;
}
if (!wlr_surface_set_role(surface, &xwayland_surface_role, w, NULL, 0))
{
fprintf (stderr, "Failed to set xwayland surface role");
wlserver_unlock();
return;
}
wlserver_unlock();
w->wlrsurface = surface;
}
@ -1587,7 +1593,9 @@ void check_new_wayland_res(void)
// Acknowledge previous one, seems we can get hangs if we don't.
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
wlserver_lock();
wlr_surface_send_frame_done(w->wlrsurface, &now);
wlserver_unlock();
}
w->committed = True;
@ -2056,7 +2064,9 @@ steamcompmgr_main (int argc, char **argv)
if ( w->wlrsurface && w->committed == True )
{
// Acknowledge commit once.
wlserver_lock();
wlr_surface_send_frame_done(w->wlrsurface, &now);
wlserver_unlock();
w->committed = False;
}

View file

@ -3,6 +3,7 @@
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <wayland-server-core.h>
#include <wlr/backend.h>
@ -164,9 +165,31 @@ int wlserver_init(int argc, char **argv, Bool bIsNested) {
return 0;
}
pthread_mutex_t waylock = PTHREAD_MUTEX_INITIALIZER;
void wlserver_lock(void)
{
pthread_mutex_lock(&waylock);
}
void wlserver_unlock(void)
{
pthread_mutex_unlock(&waylock);
}
int wlserver_run(void)
{
wl_display_run(wlserver.wl_display);
while ( 1 )
{
wlserver_lock();
wl_display_flush_clients(wlserver.wl_display);
int ret = wl_event_loop_dispatch(wlserver.wl_event_loop, 0);
wlserver_unlock();
if (ret < 0) {
break;
}
}
// We need to shutdown Xwayland before disconnecting all clients, otherwise
// wlroots will restart it automatically.
wlr_xwayland_destroy(wlserver.wlr.xwayland);

View file

@ -46,6 +46,9 @@ int wlserver_run(void);
void nudge_steamcompmgr(void);
void wlserver_lock(void);
void wlserver_unlock(void);
#ifndef C_SIDE
}
#endif