From d7cda933daa35663b2b9b61d62cb514afa37fd18 Mon Sep 17 00:00:00 2001 From: Andre Date: Fri, 7 Apr 2006 14:28:09 +0200 Subject: [PATCH 1/1] introduce para_select() A simple wrapper for select(2) that checks for EINTR and restarts the select call in this case. --- Makefile.in | 4 ++-- audioc.c | 3 ++- audiod.c | 9 +++------ configure.ac | 6 ++++-- fd.c | 13 +++++++++++++ fd.h | 3 +++ grab_client.c | 11 +++++------ gui.c | 7 +++---- play.c | 27 +++++++++++++++------------ recv.c | 5 ++--- sdl_gui.c | 4 +--- server.c | 14 ++++---------- stat.c | 7 +++---- 13 files changed, 60 insertions(+), 53 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2c64d19d..d424c538 100644 --- a/Makefile.in +++ b/Makefile.in @@ -109,8 +109,8 @@ dbadm_objs = dbadm.o exec.o close_on_fork.o string.o fade_objs = fade.cmdline.o fade.o exec.o close_on_fork.o string.o fd.o krell_objs = krell.o string.o slider_objs = slider.o string.o -audioc_objs = audioc.cmdline.o audioc.o string.o net.o -play_objs = play.cmdline.o play.o time.o +audioc_objs = audioc.cmdline.o audioc.o string.o net.o fd.o +play_objs = play.cmdline.o play.o time.o fd.o *.o: para.h config.h gcc-compat.h diff --git a/audioc.c b/audioc.c index 968f84b6..93e91178 100644 --- a/audioc.c +++ b/audioc.c @@ -22,6 +22,7 @@ #include "para.h" #include "net.h" #include "string.h" +#include "fd.h" struct gengetopt_args_info conf; char *tmpfifo; @@ -130,7 +131,7 @@ int main(int argc, char *argv[]) ret = -E_OVERRUN; if (max_fileno < 0) goto out; - ret = select(max_fileno + 1, &rfd, &wfd, NULL, NULL); + ret = para_select(max_fileno + 1, &rfd, &wfd, NULL); if (ret < 0) { ret = -E_SELECT; goto out; diff --git a/audiod.c b/audiod.c index 581cec15..9e82b13a 100644 --- a/audiod.c +++ b/audiod.c @@ -1604,14 +1604,11 @@ repeat: ret = audiod_pre_select(&rfds, &wfds, &tv); max_fileno = MAX(max_fileno, ret); - ret = select(max_fileno + 1, &rfds, &wfds, NULL, &tv); - if (ret < 0 && errno != EINTR) - PARA_ERROR_LOG("select returned %d (%s)\n", ret, - strerror(errno)); - if (audiod_status != AUDIOD_OFF) - audiod_status_dump(); + ret = para_select(max_fileno + 1, &rfds, &wfds, &tv); if (ret < 0) goto repeat; + if (audiod_status != AUDIOD_OFF) + audiod_status_dump(); audiod_post_select(ret, &rfds, &wfds); /* read status pipe */ if (stat_pipe >=0 && FD_ISSET(stat_pipe, &rfds)) { diff --git a/configure.ac b/configure.ac index 19c2ae43..f6b8733e 100644 --- a/configure.ac +++ b/configure.ac @@ -58,7 +58,8 @@ AC_CHECK_LIB([menu], [new_menu], [extras="$extras para_dbadm"], recv_cmdline_objs="recv.cmdline http_recv.cmdline dccp_recv.cmdline" -recv_errlist_objs="http_recv recv_common recv time string net dccp_recv dccp" +recv_errlist_objs="http_recv recv_common recv time string net dccp_recv + dccp fd" recv_ldflags="" filter_cmdline_objs="filter.cmdline compress_filter.cmdline" @@ -73,7 +74,8 @@ audiod_ldflags="" server_cmdline_objs="server.cmdline" server_errlist_objs="server mp3 afs command net string signal random_selector - time daemon stat crypt http_send db close_on_fork playlist_selector ipc dccp dccp_send" + time daemon stat crypt http_send db close_on_fork playlist_selector + ipc dccp dccp_send fd" server_ldflags="" ########################################################################### ssl diff --git a/fd.c b/fd.c index 5db30b63..b5310f81 100644 --- a/fd.c +++ b/fd.c @@ -12,3 +12,16 @@ int file_exists(const char *fn) return !stat(fn, &statbuf); } + +int para_select(int n, fd_set *readfds, fd_set *writefds, + struct timeval *timeout) +{ + int ret, err; + do { + ret = select(n, readfds, writefds, NULL, timeout); + err = errno; + } while (ret < 0 && errno == EINTR); + if (ret < 0) + PARA_CRIT_LOG("select error (%s)\n", strerror(err)); + return ret; +} diff --git a/fd.h b/fd.h index 30ab0852..2db28f76 100644 --- a/fd.h +++ b/fd.h @@ -19,3 +19,6 @@ /** \file fd.h file handling functions */ int file_exists(const char *); + +int para_select(int n, fd_set *readfds, fd_set *writefds, + struct timeval *timeout); diff --git a/grab_client.c b/grab_client.c index 2dfb295b..6769ee52 100644 --- a/grab_client.c +++ b/grab_client.c @@ -32,6 +32,7 @@ #include "audiod.h" #include "error.h" #include "string.h" +#include "fd.h" /** grab clients that are not yet attached to a filter node */ struct list_head inactive_grab_client_list; @@ -56,12 +57,10 @@ static int gc_write(char *buf, size_t len, struct filter_callback *fcb) // PARA_INFO_LOG("writing %d bytes to fd %d\n", len, gc->fd); fd_set wfds; - do { - FD_ZERO(&wfds); - FD_SET(gc->fd, &wfds); - ret = select(gc->fd + 1, NULL, &wfds, NULL, &tv); - } while (ret == EAGAIN || ret == EINTR); - if (ret != 1) { + FD_ZERO(&wfds); + FD_SET(gc->fd, &wfds); + ret = para_select(gc->fd + 1, NULL, &wfds, &tv); + if (ret <= 0) { if (gc->mode == GRAB_PEDANTIC) return -E_PEDANTIC_GRAB; if (gc->mode == GRAB_SLOPPY) diff --git a/gui.c b/gui.c index f63e99bd..de0e9c54 100644 --- a/gui.c +++ b/gui.c @@ -898,17 +898,16 @@ repeat: } if (curses_active) FD_SET(STDIN_FILENO, &rfds); - ret = select(max_fileno + 1, &rfds, NULL, NULL, &tv); + ret = para_select(max_fileno + 1, &rfds, NULL, &tv); // PARA_DEBUG_LOG("select returned %d\n", ret); - + if (ret <= 0) + goto check_return; /* skip fd checks */ /* signals */ if (FD_ISSET(signal_pipe, &rfds)) { int sig_nr = para_next_signal(); if (sig_nr > 0) handle_signal(sig_nr); } - if (ret <= 0) - goto check_return; /* skip fd checks */ /* read command pipe if ready */ if (command_pipe >= 0 && mode == COMMAND_MODE && FD_ISSET(command_pipe, &rfds)) { diff --git a/play.c b/play.c index 689747e9..fd8c9b28 100644 --- a/play.c +++ b/play.c @@ -25,6 +25,7 @@ #define WAV_HEADER_LEN 44 #include /* gettimeofday */ #include "para.h" +#include "fd.h" #include "play.cmdline.h" #include @@ -66,6 +67,15 @@ static size_t bytes_per_frame; static struct timeval *start_time; static struct gengetopt_args_info conf; +void para_log(__unused int ll, const char* fmt,...) +{ + va_list argp; + + va_start(argp, fmt); + vfprintf(stderr, fmt, argp); + va_end(argp); +} + /* * read_wav_header - read WAV_HEADER_LEN bytes from stdin to audio buffer * @@ -114,7 +124,7 @@ static void set_alsa_params(void) err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0); if (err < 0 || !buffer_time) EXIT(E_GET_BUFFER_TIME); - fprintf(stderr, "buffer time: %d\n", buffer_time); + PARA_DEBUG_LOG("buffer time: %d\n", buffer_time); if (snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0) < 0) EXIT(E_SET_BUFFER_TIME); @@ -122,7 +132,7 @@ static void set_alsa_params(void) EXIT(E_HW_PARAMS); snd_pcm_hw_params_get_period_size(hwparams, &chunk_size, 0); snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); - fprintf(stderr, "buffer size: %lu, period_size: %lu\n", buffer_size, chunk_size); + PARA_DEBUG_LOG("buffer size: %lu, period_size: %lu\n", buffer_size, chunk_size); if (chunk_size == buffer_size) EXIT(E_BAD_PERIOD); snd_pcm_sw_params_current(handle, swparams); @@ -163,7 +173,7 @@ static snd_pcm_sframes_t pcm_write(u_char *data, size_t count) /* write interleaved frames */ r = snd_pcm_writei(handle, data, count); if (r < 0) - fprintf(stderr, "write error: %s\n", snd_strerror(r)); + PARA_ERROR_LOG("write error: %s\n", snd_strerror(r)); if (r == -EAGAIN || (r >= 0 && r < count)) snd_pcm_wait(handle, 1); else if (r == -EPIPE) @@ -209,9 +219,8 @@ static int start_time_in_future(struct timeval *diff) */ static void do_initial_delay(struct timeval *delay) { -// fprintf(stderr, "sleeping %lums\n", tv2ms(delay)); do - select(1, NULL, NULL, NULL, delay); + para_select(1, NULL, NULL, delay); while (start_time_in_future(delay)); } @@ -248,16 +257,13 @@ again: } p = audiobuf; while (loaded >= chunk_bytes) { -// fprintf(stderr, "write (loaded = %d)\n", loaded); ret = pcm_write(p, chunk_size) * bytes_per_frame; p += ret; written += ret; loaded -= ret; } - if (loaded && p != audiobuf) { -// fprintf(stderr, "memcpy: %d@%d\n", loaded, p - audiobuf); + if (loaded && p != audiobuf) memcpy(audiobuf, p, loaded); - } read: ret = read(STDIN_FILENO, audiobuf + loaded, bufsize - loaded); if (ret < 0) @@ -282,8 +288,6 @@ static size_t check_wave(void) return WAV_HEADER_LEN; conf.channels_arg = (unsigned) a[22]; conf.sample_rate_arg = a[24] + (a[25] << 8) + (a[26] << 16) + (a[27] << 24); -// fprintf(stderr, "channels: %d, rate: %d\n", conf.channels_arg, -// conf.sample_rate_arg); return 0; } @@ -301,7 +305,6 @@ int main(int argc, char *argv[]) EXIT(E_SYNTAX); start_time = &tv; } -// fprintf(stderr, "argc=%d, argv[1]=%s\n",argc, argv[1]); snd_pcm_info_alloca(&info); if (snd_output_stdio_attach(&log, stderr, 0) < 0) EXIT(E_LOG); diff --git a/recv.c b/recv.c index fd82bc0f..ba1cfd20 100644 --- a/recv.c +++ b/recv.c @@ -19,6 +19,7 @@ #include "recv.h" #include "recv.cmdline.h" +#include "fd.h" #include "error.h" struct gengetopt_args_info conf; @@ -87,10 +88,8 @@ recv: max = MAX(max, ret); PARA_DEBUG_LOG("timeout: %lums\n", tv2ms(&timeout)); - ret = select(max + 1, &rfds, &wfds, NULL, &timeout); + ret = para_select(max + 1, &rfds, &wfds, &timeout); if (ret < 0) { - if (errno == EINTR || errno == EAGAIN) - goto recv; ret = -E_RECV_SELECT; goto out; } diff --git a/sdl_gui.c b/sdl_gui.c index d0b83f09..a1381c2f 100644 --- a/sdl_gui.c +++ b/sdl_gui.c @@ -699,13 +699,11 @@ static int draw_status(int pipe) tv.tv_usec = 3000000; FD_ZERO(&rfds); FD_SET(pipe, &rfds); - ret = select(pipe + 1, &rfds, NULL, NULL, &tv); -// printf("select returned %d\n", ret); + ret = para_select(pipe + 1, &rfds, NULL, &tv); if (ret <= 0) return 0; if (read_audiod_pipe(pipe, update_status) > 0) return 1; -// clear_all_items(); free(stat_items[SI_STATUS_BAR].content); stat_items[SI_STATUS_BAR].content = para_strdup("audiod not running!?\n"); diff --git a/server.c b/server.c index 8f20763f..2f66dc4d 100644 --- a/server.c +++ b/server.c @@ -41,6 +41,7 @@ #include "daemon.h" #include "string.h" #include "ipc.h" +#include "fd.h" /** define the array of error lists needed by para_server */ INIT_SERVER_ERRLISTS; @@ -436,7 +437,7 @@ int main(int argc, char *argv[]) /* listen on sock_fd, new connection on new_fd */ int sockfd, new_fd; struct sockaddr_in their_addr; - int err, i, max_fileno, ret; + int i, max_fileno, ret; pid_t chld_pid; fd_set rfds, wfds; struct timeval *timeout; @@ -469,21 +470,14 @@ repeat: max_fileno = MAX(max_fileno, ret); } mmd_unlock(); -// PARA_DEBUG_LOG("%s: select (max = %i)\n", __func__, max_fileno); - ret = select(max_fileno + 1, &rfds, &wfds, NULL, timeout); - err = errno; - //PARA_DEBUG_LOG("%s: select returned %i\n", __func__, ret); + ret = para_select(max_fileno + 1, &rfds, &wfds, timeout); mmd_lock(); if (mmd->selector_change >= 0) change_selector(); if (selectors[mmd->selector_num].post_select) selectors[mmd->selector_num].post_select(&rfds, &wfds); - if (ret < 0 && err == EINTR) - goto repeat; - if (ret < 0) { - PARA_CRIT_LOG("select error (%s)\n", strerror(err)); + if (ret < 0) goto repeat; - } for (i = 0; senders[i].name; i++) { if (senders[i].status != SENDER_ON) continue; diff --git a/stat.c b/stat.c index e3773df6..7346f097 100644 --- a/stat.c +++ b/stat.c @@ -25,6 +25,7 @@ #include "list.h" #include "error.h" #include "string.h" +#include "fd.h" /** the maximal number of simultaneous connections */ #define MAX_STAT_CLIENTS 50 @@ -161,10 +162,8 @@ void stat_client_write(char *msg, int itemnum) FD_ZERO(&wfds); FD_SET(fd, &wfds); // PARA_DEBUG_LOG("%s: p=%lx\n", __func__, (long)p); - do - ret = select(fd + 1, NULL, &wfds, NULL, &tv); - while (ret < 0 && errno == EINTR); - if (ret) { + ret = para_select(fd + 1, NULL, &wfds, &tv); + if (ret > 0) { ret = write(fd, msg, len); PARA_DEBUG_LOG("dumped %s to fd %d, ret = %d\n", msg, fd, ret); if (ret == len ) -- 2.39.2