From f58ab14ae2e08a6a78c483edc3cfc30055735e9f Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Sun, 3 Jun 2018 18:34:21 -0700 Subject: [PATCH] Add new timeout functions to work with inotify monitors. The ncurses timeout() function doesn't affect the new poll inside mutt_monitor_poll(). This meant that $imap_keepalive and $timeout were not being respected when the monitor was used. Create mutt_getch_timeout(), which delegates to timeout() and sets a timeout value mutt_monitor_poll() uses too. --- curs_lib.c | 23 ++++++++++++++++++----- curs_lib.h | 1 + keymap.c | 8 ++++---- monitor.c | 8 +++++++- monitor.h | 1 + 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/curs_lib.c b/curs_lib.c index fac01c5d2..63ab60f38 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -119,6 +119,19 @@ void mutt_need_hard_redraw(void) mutt_menu_set_current_redraw_full(); } +/* delay is just like for timeout() or poll(): + * the number of milliseconds mutt_getch() should block for input. + * delay == 0 means mutt_getch() is non-blocking. + * delay < 0 means mutt_getch is blocking. + */ +void mutt_getch_timeout(int delay) +{ + timeout(delay); +#ifdef USE_INOTIFY + mutt_monitor_set_poll_timeout(delay); +#endif +} + /** * mutt_getch - Read a character from the input buffer * @retval obj Event to process @@ -355,9 +368,9 @@ int mutt_yesorno(const char *msg, int def) mutt_refresh(); /* SigWinch is not processed unless timeout is set */ - timeout(30 * 1000); + mutt_getch_timeout(30 * 1000); ch = mutt_getch(); - timeout(-1); + mutt_getch_timeout(-1); if (ch.ch == -2) continue; if (CI_is_return(ch.ch)) @@ -424,7 +437,7 @@ void mutt_query_exit(void) mutt_flushinp(); curs_set(1); if (Timeout) - timeout(-1); /* restore blocking operation */ + mutt_getch_timeout(-1); /* restore blocking operation */ if (mutt_yesorno(_("Exit NeoMutt?"), MUTT_YES) == MUTT_YES) { mutt_exit(1); @@ -789,9 +802,9 @@ int mutt_multi_choice(const char *prompt, const char *letters) mutt_refresh(); /* SigWinch is not processed unless timeout is set */ - timeout(30 * 1000); + mutt_getch_timeout(30 * 1000); ch = mutt_getch(); - timeout(-1); + mutt_getch_timeout(-1); if (ch.ch == -2) continue; /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */ diff --git a/curs_lib.h b/curs_lib.h index 1e3e4ab85..6a926f85f 100644 --- a/curs_lib.h +++ b/curs_lib.h @@ -54,6 +54,7 @@ void mutt_flush_unget_to_endcond(void); void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s); void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s); struct Event mutt_getch(void); +void mutt_getch_timeout(int); int mutt_get_field_full(const char *field, char *buf, size_t buflen, int complete, bool multiple, char ***files, int *numfiles); int mutt_get_field_unbuffered(char *msg, char *buf, size_t buflen, int flags); int mutt_multi_choice(const char *prompt, const char *letters); diff --git a/keymap.c b/keymap.c index c9eebe28a..2f2072741 100644 --- a/keymap.c +++ b/keymap.c @@ -586,9 +586,9 @@ int km_dokey(int menu) { while (ImapKeepalive && ImapKeepalive < i) { - timeout(ImapKeepalive * 1000); + mutt_getch_timeout(ImapKeepalive * 1000); tmp = mutt_getch(); - timeout(-1); + mutt_getch_timeout(-1); /* If a timeout was not received, or the window was resized, exit the * loop now. Otherwise, continue to loop until reaching a total of * $timeout seconds. @@ -606,9 +606,9 @@ int km_dokey(int menu) } #endif - timeout(i * 1000); + mutt_getch_timeout(i * 1000); tmp = mutt_getch(); - timeout(-1); + mutt_getch_timeout(-1); #ifdef USE_IMAP gotkey: diff --git a/monitor.c b/monitor.c index 22fd9d630..30019cd6b 100644 --- a/monitor.c +++ b/monitor.c @@ -56,6 +56,7 @@ static struct Monitor *Monitor = NULL; static size_t PollFdsCount = 0; static size_t PollFdsLen = 0; static struct pollfd *PollFds; +static int PollTimeout = -1; struct MonitorInfo { @@ -213,6 +214,11 @@ static int monitor_handle_ignore(int desc) return new_descr; } +void mutt_monitor_set_poll_timeout(int timeout) +{ + PollTimeout = timeout; +} + #define EVENT_BUFLEN MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1) /* mutt_monitor_poll: Waits for I/O ready file descriptors or signals. @@ -236,7 +242,7 @@ int mutt_monitor_poll(void) if (INotifyFd != -1) { - fds = poll(PollFds, PollFdsLen, -1); + fds = poll(PollFds, PollFdsLen, PollTimeout); if (fds == -1) { diff --git a/monitor.h b/monitor.h index 1159abe07..d61550b05 100644 --- a/monitor.h +++ b/monitor.h @@ -29,6 +29,7 @@ struct Mailbox; int mutt_monitor_add(struct Mailbox *b); int mutt_monitor_remove(struct Mailbox *b); +void mutt_monitor_set_poll_timeout(int timeout); int mutt_monitor_poll(void); #endif /* _MUTT_MONITOR_H */ -- 2.40.0