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

View file

@ -3,6 +3,7 @@
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <wlr/backend.h> #include <wlr/backend.h>
@ -164,9 +165,31 @@ int wlserver_init(int argc, char **argv, Bool bIsNested) {
return 0; 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) 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 // We need to shutdown Xwayland before disconnecting all clients, otherwise
// wlroots will restart it automatically. // wlroots will restart it automatically.
wlr_xwayland_destroy(wlserver.wlr.xwayland); wlr_xwayland_destroy(wlserver.wlr.xwayland);

View file

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