From patchwork Sun Apr 17 13:21:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Clemens Ladisch X-Patchwork-Id: 8862821 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E494B9F1C1 for ; Sun, 17 Apr 2016 13:22:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C31F0201DD for ; Sun, 17 Apr 2016 13:22:58 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 6FEAE201B4 for ; Sun, 17 Apr 2016 13:22:57 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 6DC00261A2F; Sun, 17 Apr 2016 15:22:56 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id CBEA92650C0; Sun, 17 Apr 2016 15:22:41 +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 938EF261A8E; Sun, 17 Apr 2016 15:22:40 +0200 (CEST) Received: from dehamd003.servertools24.de (dehamd003.servertools24.de [31.47.254.18]) by alsa0.perex.cz (Postfix) with ESMTP id E5DB2264F23 for ; Sun, 17 Apr 2016 15:22:14 +0200 (CEST) Received: from [192.168.42.12] (tmo-099-127.customers.d1-online.com [80.187.99.127]) by dehamd003.servertools24.de (Postfix) with ESMTPSA id 371B7F52005C; Sun, 17 Apr 2016 15:22:14 +0200 (CEST) To: Takashi Iwai References: <570AA980.3070802@ladisch.de> <57138DC5.9050200@ladisch.de> From: Clemens Ladisch Message-ID: <57138DE7.9040206@ladisch.de> Date: Sun, 17 Apr 2016 15:21:43 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: <57138DC5.9050200@ladisch.de> X-PPP-Message-ID: <20160417132214.135824.36094@dehamd003.servertools24.de> X-PPP-Vhost: ladisch.de Cc: alsa-devel@alsa-project.org, Ricard Wanderlof , Martin Tarenskeen 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(-) no changes from v1 diff --git a/amidi/amidi.c b/amidi/amidi.c index 58ac814..290df48 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);