Fixes #150. This uses clock_gettime(CLOCK_MONOTONIC, ...) so that timestamps are always montonically increasing, and the callbacks will execute in the correct order even if the system time is adjusted in between the scheduling of callbacks.
I considered using CLOCK_BOOTTIME, but it is specific to Linux, whereas CLOCK_MONOTONIC is part of the POSIX standard. The problem from #150 could happen on any Unix platform if the clock was adjusted, either manually or by an NTP daemon.
The existing Windows implementation uses QueryPerformanceCounter(), which I believe is immune to the problem, so no change was needed there.
I have tested it using the Docker image from https://github.com/rstudio/shiny/issues/3429, and it uploading the file works without any corruption. To use it, run the following in a Docker container (on Mac, with Docker >=2.5.0.0), then visit the app at http://localhost:5099/. Then download the file, and upload it multiple times and check for any checksum mismatches.
docker run --rm -ti -p 5099:5099 fredmoser/shinyuploadissue:latest /bin/sh
apk add --no-cache g++
R -e "install.packages('remotes')"
R -e "remotes::install_github('r-lib/later@fix-clock-monotonic')"
Rscript --vanilla run.R 5099
Fixes #150. This uses
clock_gettime(CLOCK_MONOTONIC, ...)
so that timestamps are always montonically increasing, and the callbacks will execute in the correct order even if the system time is adjusted in between the scheduling of callbacks.I considered using
CLOCK_BOOTTIME
, but it is specific to Linux, whereasCLOCK_MONOTONIC
is part of the POSIX standard. The problem from #150 could happen on any Unix platform if the clock was adjusted, either manually or by an NTP daemon.The existing Windows implementation uses
QueryPerformanceCounter()
, which I believe is immune to the problem, so no change was needed there.I have tested it using the Docker image from https://github.com/rstudio/shiny/issues/3429, and it uploading the file works without any corruption. To use it, run the following in a Docker container (on Mac, with Docker >=2.5.0.0), then visit the app at http://localhost:5099/. Then download the file, and upload it multiple times and check for any checksum mismatches.