Modified startup notification logic to prevent deadlock in issue 471
git-svn-id: http://tint2.googlecode.com/svn/trunk@735 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
parent
f6b78ad094
commit
a2de8d6e53
2 changed files with 161 additions and 123 deletions
|
@ -5,7 +5,7 @@ option( ENABLE_BATTERY "Enable battery status plugin" ON )
|
|||
option( ENABLE_TINT2CONF "Enable tint2conf build, a GTK+2 theme configurator for tint2" ON )
|
||||
option( ENABLE_EXAMPLES "Install additional tin2rc examples" OFF )
|
||||
option( ENABLE_RSVG "Rsvg support (launcher only)" ON )
|
||||
option( ENABLE_SN "Startup notification support" OFF )
|
||||
option( ENABLE_SN "Startup notification support" ON )
|
||||
|
||||
include( FindPkgConfig )
|
||||
include( CheckLibraryExists )
|
||||
|
|
42
src/tint.c
42
src/tint.c
|
@ -125,6 +125,9 @@ void init (int argc, char *argv[])
|
|||
// sigprocmask(SIG_BLOCK, &block_mask, 0);
|
||||
}
|
||||
|
||||
static int sn_pipe_valid = 0;
|
||||
static int sn_pipe[2];
|
||||
|
||||
#ifdef HAVE_SN
|
||||
static int error_trap_depth = 0;
|
||||
|
||||
|
@ -145,6 +148,14 @@ static void error_trap_pop(SnDisplay *display, Display *xdisplay)
|
|||
}
|
||||
|
||||
static void sigchld_handler(int sig) {
|
||||
if (!sn_pipe_valid)
|
||||
return;
|
||||
ssize_t wur = write(sn_pipe[1], "x", 1);
|
||||
(void) wur;
|
||||
fsync(sn_pipe[1]);
|
||||
}
|
||||
|
||||
static void sigchld_handler_async() {
|
||||
// Wait for all dead processes
|
||||
pid_t pid;
|
||||
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
|
||||
|
@ -168,7 +179,8 @@ static gint cmp_ptr(gconstpointer a, gconstpointer b) {
|
|||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
static void sigchld_handler_async() {}
|
||||
#endif // HAVE_SN
|
||||
|
||||
void init_X11_pre_config()
|
||||
|
@ -204,12 +216,17 @@ void init_X11_post_config()
|
|||
server.sn_dsp = sn_display_new (server.dsp, error_trap_push, error_trap_pop);
|
||||
server.pids = g_tree_new (cmp_ptr);
|
||||
// Setup a handler for child termination
|
||||
if (pipe(sn_pipe) != 0) {
|
||||
fprintf(stderr, "Creating pipe failed.\n");
|
||||
} else {
|
||||
sn_pipe_valid = 1;
|
||||
struct sigaction act;
|
||||
memset (&act, 0, sizeof (struct sigaction));
|
||||
act.sa_handler = sigchld_handler;
|
||||
if (sigaction(SIGCHLD, &act, 0)) {
|
||||
perror("sigaction");
|
||||
}
|
||||
}
|
||||
#endif // HAVE_SN
|
||||
|
||||
imlib_context_set_display (server.dsp);
|
||||
|
@ -254,6 +271,14 @@ void cleanup()
|
|||
cleanup_server();
|
||||
cleanup_timeout();
|
||||
if (server.dsp) XCloseDisplay(server.dsp);
|
||||
|
||||
#ifdef HAVE_SN
|
||||
if (sn_pipe_valid) {
|
||||
sn_pipe_valid = 0;
|
||||
close(sn_pipe[1]);
|
||||
close(sn_pipe[0]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1106,6 +1131,11 @@ start:
|
|||
// Create a File Description Set containing x11_fd
|
||||
FD_ZERO (&fdset);
|
||||
FD_SET (x11_fd, &fdset);
|
||||
int maxfd = x11_fd;
|
||||
if (sn_pipe_valid) {
|
||||
FD_SET (sn_pipe[0], &fdset);
|
||||
maxfd = maxfd < sn_pipe[0] ? sn_pipe[0] : maxfd;
|
||||
}
|
||||
update_next_timeout();
|
||||
if (next_timeout.tv_sec >= 0 && next_timeout.tv_usec >= 0)
|
||||
timeout = &next_timeout;
|
||||
|
@ -1113,7 +1143,14 @@ start:
|
|||
timeout = 0;
|
||||
|
||||
// Wait for X Event or a Timer
|
||||
if (select(x11_fd+1, &fdset, 0, 0, timeout) > 0) {
|
||||
if (select(maxfd+1, &fdset, 0, 0, timeout) > 0) {
|
||||
if (FD_ISSET(sn_pipe[0], &fdset)) {
|
||||
char buffer[1];
|
||||
ssize_t wur = read(sn_pipe[0], buffer, 1);
|
||||
(void) wur;
|
||||
sigchld_handler_async();
|
||||
}
|
||||
if (FD_ISSET(x11_fd, &fdset)) {
|
||||
while (XPending (server.dsp)) {
|
||||
XNextEvent(server.dsp, &e);
|
||||
#if HAVE_SN
|
||||
|
@ -1352,6 +1389,7 @@ start:
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback_timeout_expired();
|
||||
|
||||
|
|
Loading…
Reference in a new issue