From patchwork Sat Aug 13 14:41:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Clemens Ladisch X-Patchwork-Id: 9278425 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DF7C2600CB for ; Sat, 13 Aug 2016 14:44:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D0CDD28A77 for ; Sat, 13 Aug 2016 14:44:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C579328A79; Sat, 13 Aug 2016 14:44:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06C5328A77 for ; Sat, 13 Aug 2016 14:44:28 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 34710266561; Sat, 13 Aug 2016 16:44:27 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 6D3A126659F; Sat, 13 Aug 2016 16:44:03 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3856F26659F; Sat, 13 Aug 2016 16:44:02 +0200 (CEST) Received: from dehamd003.servertools24.de (dehamd003.servertools24.de [31.47.254.18]) by alsa0.perex.cz (Postfix) with ESMTP id 26BDC266027 for ; Sat, 13 Aug 2016 16:43:40 +0200 (CEST) Received: from [192.168.42.232] (tmo-103-179.customers.d1-online.com [80.187.103.179]) by dehamd003.servertools24.de (Postfix) with ESMTPSA id 8E9A1F52004A; Sat, 13 Aug 2016 16:43:35 +0200 (CEST) To: Takashi Iwai References: <7982b196-edae-3330-86a8-83338e182f3e@sakamocchi.jp> <7105f8ec-be96-04af-45b0-e86326e1cf62@ladisch.de> From: Clemens Ladisch Message-ID: Date: Sat, 13 Aug 2016 16:41:58 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <7105f8ec-be96-04af-45b0-e86326e1cf62@ladisch.de> X-PPP-Message-ID: <20160813144335.946761.76561@dehamd003.servertools24.de> X-PPP-Vhost: ladisch.de Cc: alsa-devel@alsa-project.org Subject: [alsa-devel] [PATCH v2 2/2] amidi: fix timeout handling X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP The timeout is not supposed to expire when ignored messages are received. This cannot be handled with the poll() timeout, so add a separate timer. Reported-by: Martin Tarenskeen Signed-off-by: Clemens Ladisch --- amidi/amidi.c | 69 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/amidi/amidi.c b/amidi/amidi.c index 5871512..c20512c 100644 --- a/amidi/amidi.c +++ b/amidi/amidi.c @@ -25,9 +25,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -37,6 +39,8 @@ #include "aconfig.h" #include "version.h" +#define NSEC_PER_SEC 1000000000L + static int do_device_list, do_rawmidi_list; static char *port_name = "default"; static char *send_file_name; @@ -46,7 +50,7 @@ static char *send_data; static int send_data_length; static int receive_file; static int dump; -static int timeout; +static float timeout; static int stop; static snd_rawmidi_t *input, **inputp; static snd_rawmidi_t *output, **outputp; @@ -427,6 +431,7 @@ int main(int argc, char *argv[]) int ignore_active_sensing = 1; int ignore_clock = 1; int do_send_hex = 0; + struct itimerspec itimerspec = { .it_interval = { 0, 0 } }; while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { @@ -461,7 +466,7 @@ int main(int argc, char *argv[]) dump = 1; break; case 't': - timeout = atoi(optarg); + timeout = atof(optarg); break; case 'a': ignore_active_sensing = 0; @@ -552,40 +557,64 @@ int main(int argc, char *argv[]) if (inputp) { int read = 0; - int npfds, time = 0; + int npfds; struct pollfd *pfds; - timeout *= 1000; - npfds = snd_rawmidi_poll_descriptors_count(input); + npfds = 1 + snd_rawmidi_poll_descriptors_count(input); pfds = alloca(npfds * sizeof(struct pollfd)); - snd_rawmidi_poll_descriptors(input, pfds, npfds); + + if (timeout > 0) { + pfds[0].fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (pfds[0].fd == -1) { + error("cannot create timer: %s", strerror(errno)); + goto _exit; + } + pfds[0].events = POLLIN; + } else { + pfds[0].fd = -1; + } + + snd_rawmidi_poll_descriptors(input, &pfds[1], npfds - 1); + signal(SIGINT, sig_handler); + + if (timeout > 0) { + float timeout_int; + + itimerspec.it_value.tv_nsec = modff(timeout, &timeout_int) * NSEC_PER_SEC; + itimerspec.it_value.tv_sec = timeout_int; + err = timerfd_settime(pfds[0].fd, 0, &itimerspec, NULL); + if (err < 0) { + error("cannot set timer: %s", strerror(errno)); + goto _exit; + } + } for (;;) { unsigned char buf[256]; int i, length; unsigned short revents; - err = poll(pfds, npfds, 200); + err = poll(pfds, npfds, -1); if (stop || (err < 0 && errno == EINTR)) break; if (err < 0) { error("poll failed: %s", strerror(errno)); break; } - if (err == 0) { - time += 200; - if (timeout && time >= timeout) - break; - continue; - } - if ((err = snd_rawmidi_poll_descriptors_revents(input, pfds, npfds, &revents)) < 0) { + + err = snd_rawmidi_poll_descriptors_revents(input, &pfds[1], npfds - 1, &revents); + if (err < 0) { error("cannot get poll events: %s", snd_strerror(errno)); break; } if (revents & (POLLERR | POLLHUP)) break; - if (!(revents & POLLIN)) + if (!(revents & POLLIN)) { + if (pfds[0].revents & POLLIN) + break; continue; + } + err = snd_rawmidi_read(input, buf, sizeof(buf)); if (err == -EAGAIN) continue; @@ -603,7 +632,7 @@ int main(int argc, char *argv[]) if (length == 0) continue; read += length; - time = 0; + if (receive_file != -1) write(receive_file, buf, length); if (dump) { @@ -611,6 +640,14 @@ int main(int argc, char *argv[]) print_byte(buf[i]); fflush(stdout); } + + if (timeout > 0) { + err = timerfd_settime(pfds[0].fd, 0, &itimerspec, NULL); + if (err < 0) { + error("cannot set timer: %s", strerror(errno)); + break; + } + } } if (isatty(fileno(stdout))) printf("\n%d bytes read\n", read);