Test: Catch SIGUSR1 from Xvfb for X11 tests

Based on the work done by Peter Hutterer. Original commit message:

If SIGUSR1 is set to SIG_IGN, X servers (all of them, including Xvfb)
will send that signal to the parent process when they're ready to accept
connections. We can use that instead of a hardcoded sleep which brings
the wait down to ~37ms on my box.
master
Pierre Le Marre 2023-09-18 13:17:31 +02:00 committed by Wismill
parent 26b1a07659
commit 266427723a
1 changed files with 38 additions and 2 deletions

View File

@ -35,17 +35,28 @@
#include "xvfb-wrapper.h"
#include "xkbcommon/xkbcommon-x11.h"
static bool xvfb_is_ready;
static void
sigusr1_handler(int signal)
{
xvfb_is_ready = true;
}
int
xvfb_wrapper(int (*test_func)(char* display))
{
int ret = 0;
FILE * display_fd;
char display_fd_string[32];
sigset_t mask;
struct sigaction sa;
char *xvfb_argv[] = {
(char *) "Xvfb", (char *) "-displayfd", display_fd_string, NULL
};
char *envp[] = { NULL };
pid_t xvfb_pid = 0;
size_t counter = 0;
char display[32] = ":";
size_t length;
@ -57,6 +68,18 @@ xvfb_wrapper(int (*test_func)(char* display))
}
snprintf(display_fd_string, sizeof(display_fd_string), "%d", fileno(display_fd));
/* Set SIGUSR1 to SIG_IGN so Xvfb will send us that signal
* when it's ready to accept connections */
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigprocmask(SIG_BLOCK, &mask, NULL);
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
xvfb_is_ready = false;
/*
* Xvfb command: let the server find an available display.
*
@ -71,8 +94,21 @@ xvfb_wrapper(int (*test_func)(char* display))
goto err_xvfd;
}
/* Wait for Xvfb fully waking up to accept a connection from a client. */
sleep(1);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
signal(SIGUSR1, sigusr1_handler);
sigprocmask (SIG_UNBLOCK, &mask, NULL);
/* Now wait for the SIGUSR1 signal that Xvfb is ready */
while (!xvfb_is_ready) {
usleep(1000);
if (++counter >= 3000) /* 3 seconds max wait */
break;
}
signal(SIGUSR1, SIG_DFL);
/* Retrieve the display number: Xvfd writes the display number as a newline-
* terminated string; copy this number to form a proper display string. */