From henrik.bengtsson at gmail.com  Thu Oct  5 06:11:20 2017
From: henrik.bengtsson at gmail.com (Henrik Bengtsson)
Date: Wed, 4 Oct 2017 21:11:20 -0700
Subject: [Rd] socketSelect(..., timeout): non-integer timeouts in (0,
 2) (?) equal infinite timeout on Linux - weird
In-Reply-To: <CAFDcVCSfd_nx8vKLLn5oNz+JXgyn9TMEFVMxjCd2X=x2UcO+VA@mail.gmail.com>
References: <CAFDcVCSfd_nx8vKLLn5oNz+JXgyn9TMEFVMxjCd2X=x2UcO+VA@mail.gmail.com>
Message-ID: <CAFDcVCQC_nhyx8CtEbraSbJA+iyBGx1Fc=rFAFnBTj1BWRcd1Q@mail.gmail.com>

I'd like to follow up/bump the attention to this bug causing the
timeout to fail for socketSelect() on Unix.  It is still there in R
3.4.2 and R-devel.  I've identified the bug in the R source code - the
bug is due to floating-point precisions and comparison using >=.  See
PR17203 (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=17203)
for details and a patch.  I've just reverified that the patch still
solves the problem on trunk (SVN r73463).

Thanks,

/Henrik

On Sat, Oct 1, 2016 at 1:11 PM, Henrik Bengtsson
<henrik.bengtsson at gmail.com> wrote:
> There's something weird going on for certain non-integer values of
> argument 'timeout' to base::socketSelect().  For such values, there is
> no timeout and you effectively end up with an infinite timeout.   I
> can reproduce this on R 3.3.1 on Ubuntu 16.04 and RedHat 6.6, but not
> on Windows (via Linux Wine).
>
> # 1. In R master session
>> con <- socketConnection('localhost', port = 11001, server = TRUE, blocking = TRUE, open = 'a+b')
>
> # 2. In R servant session (connect to the above master socket)
>> con <- socketConnection('localhost', port = 11001, server = FALSE, blocking = TRUE, open = 'a+b')
>
> # 3. In R master session (check if there's something available on connection)
> # Wait at most 0 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 0)); print(t); print(r)
>    user  system elapsed
>       0       0       0
> [1] FALSE
>
> # Wait at most 1 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 1)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   1.002
> [1] FALSE
>
> # Wait at most 2 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 2)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   2.002
> [1] FALSE
>
> # Wait at most 2.5 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 2.5)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   2.502
> [1] FALSE
>
> # Wait at most 2.1 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 2.1)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   2.101
> [1] FALSE
>
> However, here are some weird cases where the value of the 'timeout'
> argument is ignored:
>
> # Wait at most 1.9 seconds
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 1.9)); print(t); print(r)
> ^C   user  system elapsed
>   3.780  14.888  20.594
>
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 0.1)); print(t); print(r)
> ^C   user  system elapsed
>   2.596  11.208  13.907
> [1] FALSE
>
> Note how I had to signal a user interrupt (Ctrl-C) to exit
> socketSelect().  Also, not that it still works with the timeout values
> chosen above, e.g.
>
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 0)); print(t); print(r)
>    user  system elapsed
>       0       0       0
> [1] FALSE
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 1)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   1.001
> [1] FALSE
>
>> t <- system.time(r <- socketSelect(list(con), write = FALSE, timeout = 2.1)); print(t); print(r)
>    user  system elapsed
>   0.000   0.000   2.103
> [1] FALSE
>
> It's almost as if there is something special with non-integer values
> in (0,2).  Not saying these are the only cases, but that's what I've
> observed by trial and error.  Weird.  The fact that it works on
> Windows, may suggest it is a Unix specific.  Anyway with macOS that
> wanna confirm?
>
> /Henrik
>
> Session information details:
>
> # Ubuntu 16.04
>> sessionInfo()
> R version 3.3.1 (2016-06-21)
> Platform: x86_64-pc-linux-gnu (64-bit)
> Running under: Ubuntu 16.04.1 LTS
>
> locale:
>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
>  [9] LC_ADDRESS=C               LC_TELEPHONE=C
> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> loaded via a namespace (and not attached):
> [1] tools_3.3.1
>
> # RedHat 6.6:
>> sessionInfo()
> R version 3.3.1 (2016-06-21)
> Platform: x86_64-pc-linux-gnu (64-bit)
>
> locale:
> [1] C
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> loaded via a namespace (and not attached):
> [1] tools_3.3.1
>
> # Windows via Wine on Linux
>> sessionInfo()
> R version 3.3.1 (2016-06-21)
> Platform: x86_64-w64-mingw32/x64 (64-bit)
> Running under: Windows XP x64 (build 2600) Service Pack 3
>
> locale:
> [1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
> [3] LC_MONETARY=C                         LC_NUMERIC=C
> [5] LC_TIME=C
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> loaded via a namespace (and not attached):
> [1] tools_3.3.1



[Rd] socketSelect(..., timeout): non-integer timeouts in (0, 2) (?) equal infinite timeout on Linux - weird
Henrik Bengtsson