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:
committed by
mrovi9000@gmail.com
parent
f6b78ad094
commit
a2de8d6e53
@@ -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_TINT2CONF "Enable tint2conf build, a GTK+2 theme configurator for tint2" ON )
|
||||||
option( ENABLE_EXAMPLES "Install additional tin2rc examples" OFF )
|
option( ENABLE_EXAMPLES "Install additional tin2rc examples" OFF )
|
||||||
option( ENABLE_RSVG "Rsvg support (launcher only)" ON )
|
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( FindPkgConfig )
|
||||||
include( CheckLibraryExists )
|
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);
|
// sigprocmask(SIG_BLOCK, &block_mask, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sn_pipe_valid = 0;
|
||||||
|
static int sn_pipe[2];
|
||||||
|
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
static int error_trap_depth = 0;
|
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) {
|
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
|
// Wait for all dead processes
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
|
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
|
||||||
@@ -168,7 +179,8 @@ static gint cmp_ptr(gconstpointer a, gconstpointer b) {
|
|||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static void sigchld_handler_async() {}
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
|
|
||||||
void init_X11_pre_config()
|
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.sn_dsp = sn_display_new (server.dsp, error_trap_push, error_trap_pop);
|
||||||
server.pids = g_tree_new (cmp_ptr);
|
server.pids = g_tree_new (cmp_ptr);
|
||||||
// Setup a handler for child termination
|
// 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;
|
struct sigaction act;
|
||||||
memset (&act, 0, sizeof (struct sigaction));
|
memset (&act, 0, sizeof (struct sigaction));
|
||||||
act.sa_handler = sigchld_handler;
|
act.sa_handler = sigchld_handler;
|
||||||
if (sigaction(SIGCHLD, &act, 0)) {
|
if (sigaction(SIGCHLD, &act, 0)) {
|
||||||
perror("sigaction");
|
perror("sigaction");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
|
|
||||||
imlib_context_set_display (server.dsp);
|
imlib_context_set_display (server.dsp);
|
||||||
@@ -254,6 +271,14 @@ void cleanup()
|
|||||||
cleanup_server();
|
cleanup_server();
|
||||||
cleanup_timeout();
|
cleanup_timeout();
|
||||||
if (server.dsp) XCloseDisplay(server.dsp);
|
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
|
// Create a File Description Set containing x11_fd
|
||||||
FD_ZERO (&fdset);
|
FD_ZERO (&fdset);
|
||||||
FD_SET (x11_fd, &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();
|
update_next_timeout();
|
||||||
if (next_timeout.tv_sec >= 0 && next_timeout.tv_usec >= 0)
|
if (next_timeout.tv_sec >= 0 && next_timeout.tv_usec >= 0)
|
||||||
timeout = &next_timeout;
|
timeout = &next_timeout;
|
||||||
@@ -1113,7 +1143,14 @@ start:
|
|||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
|
||||||
// Wait for X Event or a Timer
|
// 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)) {
|
while (XPending (server.dsp)) {
|
||||||
XNextEvent(server.dsp, &e);
|
XNextEvent(server.dsp, &e);
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
@@ -1352,6 +1389,7 @@ start:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callback_timeout_expired();
|
callback_timeout_expired();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user