Fix SIGUSR1 handling
Calling ev_break() in a signal handler doesn't work. Instead, we setup a libev ev_signal handler for this. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
b89dadec40
commit
531aafabb5
|
@ -435,6 +435,7 @@ typedef struct _latom {
|
||||||
|
|
||||||
#define REG_DATA_INIT { NULL, 0 }
|
#define REG_DATA_INIT { NULL, 0 }
|
||||||
|
|
||||||
|
typedef struct ev_session_signal ev_session_signal;
|
||||||
typedef struct ev_session_timer ev_session_timer;
|
typedef struct ev_session_timer ev_session_timer;
|
||||||
typedef struct ev_session_idle ev_session_idle;
|
typedef struct ev_session_idle ev_session_idle;
|
||||||
typedef struct ev_session_prepare ev_session_prepare;
|
typedef struct ev_session_prepare ev_session_prepare;
|
||||||
|
@ -755,6 +756,8 @@ typedef struct session {
|
||||||
/// so we can be sure if xcb read from X socket at anytime during event
|
/// so we can be sure if xcb read from X socket at anytime during event
|
||||||
/// handling, we will not left any event unhandled in the queue
|
/// handling, we will not left any event unhandled in the queue
|
||||||
ev_session_prepare *event_check;
|
ev_session_prepare *event_check;
|
||||||
|
/// Signal handler for SIGUSR1
|
||||||
|
ev_session_signal *usr1_signal;
|
||||||
/// Whether we have hit unredirection timeout.
|
/// Whether we have hit unredirection timeout.
|
||||||
bool tmout_unredir_hit;
|
bool tmout_unredir_hit;
|
||||||
/// Whether we need to redraw the screen
|
/// Whether we need to redraw the screen
|
||||||
|
|
|
@ -53,9 +53,6 @@ cxinerama_upd_scrs(session_t *ps);
|
||||||
static void
|
static void
|
||||||
session_destroy(session_t *ps);
|
session_destroy(session_t *ps);
|
||||||
|
|
||||||
static void
|
|
||||||
reset_enable(int __attribute__((unused)) signum);
|
|
||||||
|
|
||||||
#ifdef CONFIG_XINERAMA
|
#ifdef CONFIG_XINERAMA
|
||||||
static void
|
static void
|
||||||
cxinerama_upd_scrs(session_t *ps);
|
cxinerama_upd_scrs(session_t *ps);
|
||||||
|
@ -128,20 +125,25 @@ render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
xcb_render_picture_t pict, glx_texture_t *ptex,
|
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||||
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
||||||
|
|
||||||
typedef struct ev_session_timer {
|
struct ev_session_timer {
|
||||||
ev_timer w;
|
ev_timer w;
|
||||||
session_t *ps;
|
session_t *ps;
|
||||||
} ev_session_timer;
|
};
|
||||||
|
|
||||||
typedef struct ev_session_idle {
|
struct ev_session_idle {
|
||||||
ev_idle w;
|
ev_idle w;
|
||||||
session_t *ps;
|
session_t *ps;
|
||||||
} ev_session_idle;
|
};
|
||||||
|
|
||||||
typedef struct ev_session_prepare {
|
struct ev_session_prepare {
|
||||||
ev_prepare w;
|
ev_prepare w;
|
||||||
session_t *ps;
|
session_t *ps;
|
||||||
} ev_session_prepare;
|
};
|
||||||
|
|
||||||
|
struct ev_session_signal {
|
||||||
|
ev_signal w;
|
||||||
|
session_t *ps;
|
||||||
|
};
|
||||||
|
|
||||||
// === Global constants ===
|
// === Global constants ===
|
||||||
|
|
||||||
|
@ -222,8 +224,8 @@ static const char *background_props_str[] = {
|
||||||
// === Global variables ===
|
// === Global variables ===
|
||||||
|
|
||||||
/// Pointer to current session, as a global variable. Only used by
|
/// Pointer to current session, as a global variable. Only used by
|
||||||
/// <code>error()</code> and <code>reset_enable()</code>, which could not
|
/// xerror(), which could not have a pointer to current session passed in.
|
||||||
/// have a pointer to current session passed in.
|
/// XXX Limit what xerror can access by not having this pointer
|
||||||
session_t *ps_g = NULL;
|
session_t *ps_g = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5010,6 +5012,17 @@ x_event_callback(EV_P_ ev_io *w, int revents) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn on the program reset flag.
|
||||||
|
*
|
||||||
|
* This will result in compton resetting itself after next paint.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
reset_enable(EV_P_ ev_signal *w, int revents) {
|
||||||
|
session_t *ps = ((ev_session_signal *)w)->ps;
|
||||||
|
ev_break(ps->loop, EVBREAK_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a session.
|
* Initialize a session.
|
||||||
*
|
*
|
||||||
|
@ -5493,6 +5506,12 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
ps->delayed_draw_timer->ps = ps;
|
ps->delayed_draw_timer->ps = ps;
|
||||||
ev_init(&ps->delayed_draw_timer->w, delayed_draw_timer_callback);
|
ev_init(&ps->delayed_draw_timer->w, delayed_draw_timer_callback);
|
||||||
|
|
||||||
|
// Set up SIGUSR1 signal handler to reset program
|
||||||
|
ps->usr1_signal = calloc(1, sizeof(ev_session_signal));
|
||||||
|
ps->usr1_signal->ps = ps;
|
||||||
|
ev_signal_init(&ps->usr1_signal->w, reset_enable, SIGUSR1);
|
||||||
|
ev_signal_start(ps->loop, &ps->usr1_signal->w);
|
||||||
|
|
||||||
// xcb can read multiple events from the socket when a request with reply is
|
// xcb can read multiple events from the socket when a request with reply is
|
||||||
// made.
|
// made.
|
||||||
//
|
//
|
||||||
|
@ -5761,6 +5780,10 @@ session_destroy(session_t *ps) {
|
||||||
free(ps->event_check);
|
free(ps->event_check);
|
||||||
ps->event_check = NULL;
|
ps->event_check = NULL;
|
||||||
|
|
||||||
|
ev_signal_stop(ps->loop, &ps->usr1_signal->w);
|
||||||
|
free(ps->usr1_signal);
|
||||||
|
ps->usr1_signal = NULL;
|
||||||
|
|
||||||
if (ps == ps_g)
|
if (ps == ps_g)
|
||||||
ps_g = NULL;
|
ps_g = NULL;
|
||||||
}
|
}
|
||||||
|
@ -5798,17 +5821,6 @@ session_run(session_t *ps) {
|
||||||
ev_run(ps->loop, 0);
|
ev_run(ps->loop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on the program reset flag.
|
|
||||||
*
|
|
||||||
* This will result in compton resetting itself after next paint.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
reset_enable(int __attribute__((unused)) signum) {
|
|
||||||
session_t * const ps = ps_g;
|
|
||||||
ev_break(ps->loop, EVBREAK_ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sigint_handler(int __attribute__((unused)) signum) {
|
sigint_handler(int __attribute__((unused)) signum) {
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -5823,16 +5835,8 @@ main(int argc, char **argv) {
|
||||||
// correctly
|
// correctly
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
// Set up SIGUSR1 signal handler to reset program
|
|
||||||
sigset_t sigmask;
|
sigset_t sigmask;
|
||||||
sigemptyset(&sigmask);
|
sigemptyset(&sigmask);
|
||||||
const struct sigaction usr1_action = {
|
|
||||||
.sa_handler = reset_enable,
|
|
||||||
.sa_mask = sigmask,
|
|
||||||
.sa_flags = 0
|
|
||||||
};
|
|
||||||
sigaction(SIGUSR1, &usr1_action, NULL);
|
|
||||||
|
|
||||||
const struct sigaction int_action = {
|
const struct sigaction int_action = {
|
||||||
.sa_handler = sigint_handler,
|
.sa_handler = sigint_handler,
|
||||||
.sa_mask = sigmask,
|
.sa_mask = sigmask,
|
||||||
|
|
Loading…
Reference in New Issue