]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gui.c
string: Speed up xvasprintf().
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index a34f27de5e40cb0adbb2d652d18586c955d88a90..85d77c9e581d060c5a97c543361aaf95a499ee21 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -10,6 +10,7 @@
 #include <signal.h>
 #include <sys/types.h>
 #include <curses.h>
+#include <sys/time.h>
 
 #include "gui.cmdline.h"
 #include "para.h"
@@ -287,14 +288,20 @@ static char *configfile_exists(void)
        return file_exists(tmp)? tmp: NULL;
 }
 
-/*
- * print num spaces to curses window
- */
+/* Print given number of spaces to curses window. */
 static void add_spaces(WINDOW* win, unsigned int num)
 {
-       while (num > 0) {
-               num--;
-               waddstr(win, " ");
+       char space[] = "                                ";
+       unsigned sz = sizeof(space);
+
+       while (num >= sz)  {
+               waddstr(win, space);
+               num -= sz;
+       }
+       if (num > 0) {
+               assert(num < sz);
+               space[num] = '\0';
+               waddstr(win, space);
        }
 }
 
@@ -924,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
@@ -972,6 +982,7 @@ static int do_select(int mode)
        char command_buf[2][COMMAND_BUF_SIZE] = {"", ""};
        int cbo[2] = {0, 0}; /* command buf offsets */
        struct timeval tv;
+       unsigned flags[2] = {0, 0}; /* for for_each_line() */
 
 repeat:
        tv.tv_sec = conf.timeout_arg  / 1000;
@@ -979,10 +990,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 */
@@ -1012,21 +1020,25 @@ repeat:
                                COMMAND_BUF_SIZE - 1 - cbo[i], &rfds, &sz);
                        cbo[i] += sz;
                        sz = cbo[i];
-                       cbo[i] = for_each_line(command_buf[i], cbo[i],
+                       cbo[i] = for_each_line(flags[i], command_buf[i], cbo[i],
                                add_output_line, &i);
-                       if (sz != cbo[i])
+                       if (sz != cbo[i]) { /* at least one line found */
                                wrefresh(bot.win);
+                               flags[i] = 0;
+                       }
                        if (ret < 0) {
                                PARA_NOTICE_LOG("closing command fd %d: %s",
                                        i, para_strerror(-ret));
                                close(command_fds[i]);
                                command_fds[i] = -1;
+                               flags[i] = 0;
                                if (command_fds[!i] < 0) /* both fds closed */
                                        return 0;
                        }
                        if (cbo[i] == COMMAND_BUF_SIZE - 1) {
                                PARA_NOTICE_LOG("discarding overlong line");
                                cbo[i] = 0;
+                               flags[i] = FELF_DISCARD_FIRST;
                        }
                }
        }