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
parent
26b1a07659
commit
266427723a
|
@ -35,17 +35,28 @@
|
||||||
#include "xvfb-wrapper.h"
|
#include "xvfb-wrapper.h"
|
||||||
#include "xkbcommon/xkbcommon-x11.h"
|
#include "xkbcommon/xkbcommon-x11.h"
|
||||||
|
|
||||||
|
static bool xvfb_is_ready;
|
||||||
|
|
||||||
|
static void
|
||||||
|
sigusr1_handler(int signal)
|
||||||
|
{
|
||||||
|
xvfb_is_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xvfb_wrapper(int (*test_func)(char* display))
|
xvfb_wrapper(int (*test_func)(char* display))
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
FILE * display_fd;
|
FILE * display_fd;
|
||||||
char display_fd_string[32];
|
char display_fd_string[32];
|
||||||
|
sigset_t mask;
|
||||||
|
struct sigaction sa;
|
||||||
char *xvfb_argv[] = {
|
char *xvfb_argv[] = {
|
||||||
(char *) "Xvfb", (char *) "-displayfd", display_fd_string, NULL
|
(char *) "Xvfb", (char *) "-displayfd", display_fd_string, NULL
|
||||||
};
|
};
|
||||||
char *envp[] = { NULL };
|
char *envp[] = { NULL };
|
||||||
pid_t xvfb_pid = 0;
|
pid_t xvfb_pid = 0;
|
||||||
|
size_t counter = 0;
|
||||||
char display[32] = ":";
|
char display[32] = ":";
|
||||||
size_t length;
|
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));
|
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.
|
* Xvfb command: let the server find an available display.
|
||||||
*
|
*
|
||||||
|
@ -71,8 +94,21 @@ xvfb_wrapper(int (*test_func)(char* display))
|
||||||
goto err_xvfd;
|
goto err_xvfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for Xvfb fully waking up to accept a connection from a client. */
|
sa.sa_handler = SIG_DFL;
|
||||||
sleep(1);
|
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-
|
/* Retrieve the display number: Xvfd writes the display number as a newline-
|
||||||
* terminated string; copy this number to form a proper display string. */
|
* terminated string; copy this number to form a proper display string. */
|
||||||
|
|
Loading…
Reference in New Issue