Thanks Eric, that makes things a lot cleaner, more resilient and, at a
guess, more portable (surely any OS with select will have O_NONBLOCK?)

  I agree it's more a performance bug but, I think, if select returns a
spurious wakeup then the read should set EAGAIN (EWOULDBLOCK) - which
the Linux 3.13.0-65.105-generic kernel doesn't.  (Not that this would
have helped the unpatched sox).

  Cheers,
    Tarim


Eric Wong wrote:
> Tarim <s...@mediaplaygrounds.co.uk> wrote:
>>   I'm now thinking that this is actually a bug in the latest Ubuntu
>> kernel
>> 3.13.0-65.105-generic where select's FD_ISSET returns true even when
>> there is no data to read!
>
> This is a kernel bug from a performance standpoint, but the select
> manpage explicitly documents spurious wakeups as a possibility which
> userspace must be prepared for.
>
> The following patch should fix the problem:
>
> ------------------8<------------------
> Subject: [PATCH] use non-blocking stdin for interactive mode
>
> When accepting keyboard input, it is possible for select() to
> return a false-positive with spurious wakeups from inside the
> update_status callback.
>
> Using the FIONREAD ioctl in place of select is also a possibility,
> but may be less portable.
> ---
>   Downloadable patch:
>   http://80x24.org/spew/1443909787-27821-1-git-send-email-e%4080x24.org/raw
>
>   In case upstream prefers a pull request:
>
>   The following changes since commit
> 7e74b254b2a7c963be0bfce751fc5911fe681c12:
>
>     Remove hepler script. It's mostly unmaintained, I don't know if anyone
> but me ever used it. In any case, those who want a custom Debian
> package should be capable of updating the debian/changelog entry on
> their own. (2015-02-26 22:48:40 -0500)
>
>   are available in the git repository at:
>
>     git://bogomips.org/sox nb-stdin
>
>   for you to fetch changes up to 62a370a2a01cf1dcc0d5f9b9f49d1515706346cd:
>
>     use non-blocking stdin for interactive mode (2015-10-03 22:04:50
> +0000)
>
>   ----------------------------------------------------------------
>   Eric Wong (1):
>         use non-blocking stdin for interactive mode
>
>  src/sox.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/src/sox.c b/src/sox.c
> index bab0f45..fdb7616 100644
> --- a/src/sox.c
> +++ b/src/sox.c
> @@ -1789,6 +1789,18 @@ static int process(void)
>      tcsetattr(fileno(stdin), TCSANOW, &modified_termios);
>    }
>  #endif
> +#if defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK)
> +  if (interactive) {
> +    int fd = fileno(stdin);
> +    int flags = fcntl(fd, F_GETFL);
> +    if (flags == -1) {
> +      lsx_warn("error getting flags on stdin descriptor: %s",
> strerror(errno));
> +    } else if (!(flags & O_NONBLOCK)) {
> +      if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
> +        lsx_warn("error setting non-blocking on stdin: %s",
> strerror(errno));
> +    }
> +  }
> +#endif
>
>    signal(SIGTERM, sigint); /* Stop gracefully, as soon as we possibly
> can. */
>    signal(SIGINT , sigint); /* Either skip current input or behave as
> SIGTERM. */
> --
> EW
>


------------------------------------------------------------------------------
_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel

Reply via email to