From fdd8a22e1df57a8c9254e7d0074301e7dde2c557 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 24 Sep 2021 18:11:06 +0200 Subject: [PATCH] sched: Use integer value for select timeout. This modifies the public struct sched so that users pass in the default timeout as an integer value in milliseconds rather than a struct timeval. This simplifies the code a little and eases the transition from select(2) to poll(2) because poll(2) also takes a plain integer for the timeout. Since para_select() of fd.c now calls ms2tv() to convert the timeout back to a struct timeval, all executables which link with fd.o must also link with time.o. This was not the case for para_mixer and para_audioc, so configure.ac needs to be adjusted accordingly. --- afs.c | 3 +-- audioc.c | 2 +- audiod.c | 3 +-- client.c | 4 ++-- configure.ac | 4 ++-- fd.c | 16 +++++++--------- fd.h | 3 +-- filter.c | 3 +-- gui.c | 2 +- interactive.c | 14 ++++++++------ interactive.h | 3 +-- play.c | 2 +- recv.c | 3 +-- sched.c | 11 ++++++----- sched.h | 10 +++++----- server.c | 6 +++--- write.c | 3 +-- 17 files changed, 43 insertions(+), 49 deletions(-) diff --git a/afs.c b/afs.c index 71067025..c216b354 100644 --- a/afs.c +++ b/afs.c @@ -1003,8 +1003,7 @@ __noreturn void afs_init(int socket_fd) PARA_INFO_LOG("server_socket: %d\n", server_socket); init_admissible_files(OPT_STRING_VAL(AFS_INITIAL_MODE)); register_command_task(&s); - s.default_timeout.tv_sec = 0; - s.default_timeout.tv_usec = 999 * 1000; + s.default_timeout = 1000; ret = write(socket_fd, "\0", 1); if (ret != 1) { if (ret == 0) diff --git a/audioc.c b/audioc.c index af670633..76b3d6db 100644 --- a/audioc.c +++ b/audioc.c @@ -252,7 +252,7 @@ __noreturn static void interactive_session(void) sigaction(SIGINT, &act, NULL); sched.select_function = i9e_select; - sched.default_timeout.tv_sec = 1; + sched.default_timeout = 1000; ret = i9e_open(&ici, &sched); if (ret < 0) goto out; diff --git a/audiod.c b/audiod.c index 119adbc0..8e1da6e8 100644 --- a/audiod.c +++ b/audiod.c @@ -1510,8 +1510,7 @@ int main(int argc, char *argv[]) .context = signal_task, }, &sched); - sched.default_timeout.tv_sec = 2; - sched.default_timeout.tv_usec = 999 * 1000; + sched.default_timeout = 2999; ret = schedule(&sched); audiod_cleanup(); sched_shutdown(&sched); diff --git a/client.c b/client.c index 8caf4483..24f9c61c 100644 --- a/client.c +++ b/client.c @@ -123,7 +123,7 @@ fail: static int execute_client_command(const char *cmd, char **result) { int ret; - struct sched command_sched = {.default_timeout = {.tv_sec = 1}}; + struct sched command_sched = {.default_timeout = 1000}; struct exec_task exec_task = { .result_buf = para_strdup(""), .result_size = 1, @@ -624,7 +624,7 @@ int main(int argc, char *argv[]) int ret; crypt_init(); - sched.default_timeout.tv_sec = 1; + sched.default_timeout = 1000; ret = client_parse_config(argc, argv, &ct, &client_loglevel); if (ret < 0) diff --git a/configure.ac b/configure.ac index b817979f..0e37e39e 100644 --- a/configure.ac +++ b/configure.ac @@ -586,7 +586,7 @@ fi if test $HAVE_OSS = yes -o $HAVE_ALSA = yes; then build_mixer="yes" executables="$executables mixer" - mixer_errlist_objs="mixer exec string fd lsu version" + mixer_errlist_objs="mixer exec string fd time lsu version" if test $HAVE_OSS = yes; then mixer_errlist_objs="$mixer_errlist_objs oss_mix" fi @@ -842,6 +842,7 @@ audioc_errlist_objs=" lsu net fd + time version " if test $HAVE_READLINE = yes; then @@ -849,7 +850,6 @@ if test $HAVE_READLINE = yes; then buffer_tree interactive sched - time " fi audioc_objs="$audioc_errlist_objs" diff --git a/fd.c b/fd.c index 33891d2e..d72096e1 100644 --- a/fd.c +++ b/fd.c @@ -334,8 +334,7 @@ bool file_exists(const char *fn) * \param n The highest-numbered descriptor in any of the two sets, plus 1. * \param readfds fds that should be checked for readability. * \param writefds fds that should be checked for writablility. - * \param timeout_tv upper bound on the amount of time elapsed before select() - * returns. + * \param timeout Upper bound in milliseconds. * * \return The return value of the underlying select() call on success, the * negative system error code on errors. @@ -343,12 +342,14 @@ bool file_exists(const char *fn) * All arguments are passed verbatim to select(2). * \sa select(2) select_tut(2). */ -int para_select(int n, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv) +int para_select(int n, fd_set *readfds, fd_set *writefds, int timeout) { int ret; + struct timeval tv; + + ms2tv(timeout, &tv); do - ret = select(n, readfds, writefds, NULL, timeout_tv); + ret = select(n, readfds, writefds, NULL, &tv); while (ret < 0 && errno == EINTR); if (ret < 0) return -ERRNO_TO_PARA_ERROR(errno); @@ -653,14 +654,11 @@ int para_munmap(void *start, size_t length) int write_ok(int fd) { - struct timeval tv; fd_set wfds; FD_ZERO(&wfds); FD_SET(fd, &wfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - return para_select(fd + 1, NULL, &wfds, &tv); + return para_select(fd + 1, NULL, &wfds, 0); } /** diff --git a/fd.h b/fd.h index c9e79426..820e1cc9 100644 --- a/fd.h +++ b/fd.h @@ -6,8 +6,7 @@ int xrename(const char *oldpath, const char *newpath); int write_all(int fd, const char *buf, size_t len); __printf_2_3 int write_va_buffer(int fd, const char *fmt, ...); bool file_exists(const char *); -int para_select(int n, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv); +int para_select(int n, fd_set *readfds, fd_set *writefds, int timeout); __must_check int mark_fd_nonblocking(int fd); __must_check int mark_fd_blocking(int fd); void para_fd_set(int fd, fd_set *fds, int *max_fileno); diff --git a/filter.c b/filter.c index d4a24239..95438779 100644 --- a/filter.c +++ b/filter.c @@ -149,8 +149,7 @@ int main(int argc, char *argv[]) EMBRACE(.name = "stdout", .parent = parent)); stdout_task_register(sot, &s); - s.default_timeout.tv_sec = 1; - s.default_timeout.tv_usec = 0; + s.default_timeout = 1000; btr_log_tree(sit->btrn, LL_INFO); ret = schedule(&s); sched_shutdown(&s); diff --git a/gui.c b/gui.c index d779ff86..7a859a0c 100644 --- a/gui.c +++ b/gui.c @@ -1391,7 +1391,7 @@ static int setup_tasks_and_schedule(void) struct status_task status_task = {.fd = -1}; struct input_task input_task = {.task = NULL}; struct signal_task *signal_task; - struct sched sched = {.default_timeout = {.tv_sec = 1}}; + struct sched sched = {.default_timeout = 1000}; exec_task.task = task_register(&(struct task_info) { .name = "exec", diff --git a/interactive.c b/interactive.c index 041376a1..8e614840 100644 --- a/interactive.c +++ b/interactive.c @@ -261,12 +261,11 @@ static void clear_bottom_line(void) static bool input_available(void) { fd_set rfds; - struct timeval tv = {0, 0}; int ret; FD_ZERO(&rfds); FD_SET(i9ep->ici->fds[0], &rfds); - ret = para_select(1, &rfds, NULL, &tv); + ret = para_select(1, &rfds, NULL, 0); return ret > 0; } @@ -610,17 +609,20 @@ void i9e_signal_dispatch(int sig_num) * \param n \sa \ref para_select(). * \param readfds \sa \ref para_select(). * \param writefds \sa \ref para_select(). - * \param timeout_tv \sa \ref para_select(). + * \param timeout \sa \ref para_select(). * * \return \sa \ref para_select(). * * The only difference between this function and \ref para_select() is that * \ref i9e_select() returns zero if the select call returned \p EINTR. */ -int i9e_select(int n, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv) +int i9e_select(int n, fd_set *readfds, fd_set *writefds, int timeout) { - int ret = select(n, readfds, writefds, NULL, timeout_tv); + struct timeval tv; + int ret; + + ms2tv(timeout, &tv); + ret = select(n, readfds, writefds, NULL, &tv); if (ret < 0) { if (errno == EINTR) diff --git a/interactive.h b/interactive.h index ddf02d76..4253f79c 100644 --- a/interactive.h +++ b/interactive.h @@ -84,8 +84,7 @@ void i9e_print_status_bar(char *buf, unsigned len); void i9e_close(void); void i9e_signal_dispatch(int sig_num); __printf_2_3 void i9e_log(int ll, const char* fmt,...); -int i9e_select(int n, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv); +int i9e_select(int n, fd_set *readfds, fd_set *writefds, int timeout); int i9e_extract_completions(const char *word, char **string_list, char ***result); char **i9e_complete_commands(const char *word, struct i9e_completer *completers); diff --git a/play.c b/play.c index ba9fff70..0c78b960 100644 --- a/play.c +++ b/play.c @@ -1255,7 +1255,7 @@ int main(int argc, char *argv[]) int ret; unsigned num_inputs; - sched.default_timeout.tv_sec = 5; + sched.default_timeout = 5000; parse_config_or_die(argc, argv); session_open(); num_inputs = lls_num_inputs(play_lpr); diff --git a/recv.c b/recv.c index 10d55d21..a81eebb8 100644 --- a/recv.c +++ b/recv.c @@ -102,8 +102,7 @@ int main(int argc, char *argv[]) ti.context = &rn; rn.task = task_register(&ti, &s); - s.default_timeout.tv_sec = 1; - s.default_timeout.tv_usec = 0; + s.default_timeout = 1000; ret = schedule(&s); sched_shutdown(&s); r->close(&rn); diff --git a/sched.c b/sched.c index aac8efed..8deb7f38 100644 --- a/sched.c +++ b/sched.c @@ -137,12 +137,12 @@ int schedule(struct sched *s) again: FD_ZERO(&s->rfds); FD_ZERO(&s->wfds); - s->select_timeout = s->default_timeout; + s->timeout = s->default_timeout; s->max_fileno = -1; clock_get_realtime(&now_struct); sched_preselect(s); ret = s->select_function(s->max_fileno + 1, &s->rfds, &s->wfds, - &s->select_timeout); + s->timeout); if (ret < 0) return ret; if (ret == 0) { @@ -370,7 +370,7 @@ void task_notify_all(struct sched *s, int err) */ void sched_min_delay(struct sched *s) { - s->select_timeout.tv_sec = s->select_timeout.tv_usec = 0; + s->timeout = 0; } /** @@ -387,8 +387,9 @@ void sched_min_delay(struct sched *s) */ void sched_request_timeout(struct timeval *to, struct sched *s) { - if (tv_diff(&s->select_timeout, to, NULL) > 0) - s->select_timeout = *to; + long unsigned ms = tv2ms(to); + if (s->timeout > ms) + s->timeout = ms; } /** diff --git a/sched.h b/sched.h index 35e2503e..4695da05 100644 --- a/sched.h +++ b/sched.h @@ -13,10 +13,10 @@ * called after the select call. */ struct sched { - /** Initial value before any pre_select call. */ - struct timeval default_timeout; - /** The current timeout for the upcoming select call. */ - struct timeval select_timeout; + /** Initial value (in milliseconds) before any pre_select call. */ + int default_timeout; + /** The timeout (also in milliseconds) for the next select call. */ + int timeout; /** fds that should be watched for readability. */ fd_set rfds; /** fds that should be watched for writability. */ @@ -24,7 +24,7 @@ struct sched { /** Highest numbered file descriptor in any of the above fd sets. */ int max_fileno; /** If non-NULL, use this function instead of para_select. */ - int (*select_function)(int, fd_set *, fd_set *, struct timeval *); + int (*select_function)(int, fd_set *, fd_set *, int timeout); /** Tasks which have been registered to the scheduler. */ struct list_head task_list; }; diff --git a/server.c b/server.c index e0df714b..729ca1ac 100644 --- a/server.c +++ b/server.c @@ -618,13 +618,13 @@ out: } static int server_select(int max_fileno, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv) + int timeout) { int ret; status_refresh(); mutex_unlock(mmd_mutex); - ret = para_select(max_fileno + 1, readfds, writefds, timeout_tv); + ret = para_select(max_fileno + 1, readfds, writefds, timeout); mutex_lock(mmd_mutex); return ret; } @@ -658,7 +658,7 @@ int main(int argc, char *argv[]) struct server_command_task server_command_task_struct, *sct = &server_command_task_struct; - sched.default_timeout.tv_sec = 1; + sched.default_timeout = 1000; sched.select_function = server_select; server_init(argc, argv, sct); diff --git a/write.c b/write.c index acfb9460..177b2e66 100644 --- a/write.c +++ b/write.c @@ -96,8 +96,7 @@ static int setup_and_schedule(struct lls_parse_result *lpr) wns[i].wid = check_writer_arg_or_die(arg, &wns[i].lpr); register_writer_node(wns + i, cw_btrn, &s); } - s.default_timeout.tv_sec = 10; - s.default_timeout.tv_usec = 50000; + s.default_timeout = 10500; ret = schedule(&s); if (ret >= 0) { int j, ts; -- 2.39.2