From 14e6890c756529c73a95cf1fb3648a6a7c3344d7 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 27 Mar 2013 20:49:40 +0000 Subject: [PATCH] gui: Don't sleep before executing the status command. This results in uncacceptable delays when the status command fails for any reason, for example because the server is down. Replace this code by introducing a struct timeval variable "next_exec", which stores the earliest possible time to restart the status command. Move all status fetching code before the select() call in do_select() to open_stat_pipe() and rename the function to status_pre_select(), which is more appropriate. --- configure.ac | 2 +- gui.c | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 4512c6fd..35c9fd58 100644 --- a/configure.ac +++ b/configure.ac @@ -153,7 +153,7 @@ client_errlist_objs="client net string fd sched stdin stdout time sideband client_ldflags="" gui_cmdline_objs="add_cmdline(gui)" -gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme" +gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme time" gui_objs="$gui_cmdline_objs $gui_errlist_objs" play_errlist_objs="play fd sched ggo buffer_tree time string net afh_recv afh_common diff --git a/gui.c b/gui.c index 6e44b09d..fb70dd83 100644 --- a/gui.c +++ b/gui.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "gui.cmdline.h" #include "para.h" @@ -930,30 +931,33 @@ static void handle_signal(int sig) } } -static int open_stat_pipe(void) +static void status_pre_select(fd_set *rfds, int *max_fileno, struct timeval *tv) { - static int init = 1; + static struct timeval next_exec, atm, diff; int ret, fds[3] = {0, 1, 0}; pid_t pid; - if (init) - init = 0; - else - /* - * Sleep a bit to avoid a busy loop. As the call to sleep() may - * be interrupted by SIGCHLD, we simply wait until the call - * succeeds. - */ - while (sleep(2)) - ; /* nothing */ + if (stat_pipe >= 0) + goto success; + /* Avoid busy loop */ + gettimeofday(&atm, NULL); + if (tv_diff(&next_exec, &atm, &diff) > 0) { + if (tv_diff(&diff, tv, NULL) < 0) + *tv = diff; + return; + } + next_exec.tv_sec = atm.tv_sec + 2; ret = para_exec_cmdline_pid(&pid, conf.stat_cmd_arg, fds); if (ret < 0) - return ret; + return; ret = mark_fd_nonblocking(fds[1]); - if (ret >= 0) - return fds[1]; - close(fds[1]); - return ret; + if (ret < 0) { + close(fds[1]); + return; + } + stat_pipe = fds[1]; +success: + para_fd_set(stat_pipe, rfds, max_fileno); } #define COMMAND_BUF_SIZE 32768 @@ -985,10 +989,7 @@ repeat: // ret = refresh_status(); FD_ZERO(&rfds); max_fileno = 0; - if (stat_pipe < 0) - stat_pipe = open_stat_pipe(); - if (stat_pipe >= 0) - para_fd_set(stat_pipe, &rfds, &max_fileno); + status_pre_select(&rfds, &max_fileno, &tv); /* signal pipe */ para_fd_set(signal_pipe, &rfds, &max_fileno); /* command pipe only for COMMAND_MODE */ -- 2.39.2