Bug 51766 - Thread.Sleep gets stuck if system clock is set to an earlier time
Summary: Thread.Sleep gets stuck if system clock is set to an earlier time
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer ()
Version: 4.8.0 (C9)
Hardware: PC Linux
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-01-25 14:35 UTC by Brandon White
Modified: 2017-09-07 20:30 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Minimally reproducing test program (3.96 KB, application/x-7z-compressed)
2017-01-25 14:35 UTC, Brandon White
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Brandon White 2017-01-25 14:35:13 UTC
Created attachment 19476 [details]
Minimally reproducing test program

The Mono runtime appears to incorrectly rely on the system clock for operations that are supposed to have monotonic behavior. Thread.Sleep should not be affected by system clock changes, but it clearly is in Mono. 

An attached test program demonstrates the issue.  If the system clock is set back to an earlier time while a Thread.Sleep call is active, it will not return until the system clock catches back up to the time it was previously set when Thread.Sleep was called.  This breaks many applications, causing services to hang or become temporarily unavailable whenever time adjustments are made.

While the test application is running this loop:

            while(!Console.KeyAvailable)
            {
                Console.Write(".");
                Thread.Sleep(500);
            }

Set the system clock to a time earlier/before the current time.  For example, set it back 1 minute or 1 hour.  You will immediately notice the console dot output stops!  The loop and output will resume once the system clock advances to the previous time.


Mono JIT compiler version 4.8.0 (Stable 4.8.0.472/6f90ed1 Tue Jan 24 13:23:36 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

and

Mono JIT compiler version 4.8.0 (tarball Thu Jan 12 15:48:58 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       normal
        Notifications: epoll
        Architecture:  armel,vfp+fallback
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen
Comment 1 Roman 2017-02-28 09:24:23 UTC
I've noticed such bug on my Arch Linux.
Thread.Sleep(...) does not work after set date time.
I've reproduced such experiment - I've written two application with familiar code:
first is typed using C#, second is typed using C++.

Code C#:

    class Program
    {
        static void Main(string[] args)
        {
            int i = 0;
            while (true)
            {
                Console.WriteLine("C#: {0}", i++);
                Thread.Sleep(990);
            }
        }
    }

Code C++:

#include <iostream>
#include <cstdlib>
#include <unistd.h>

using namespace std;

void main (int argc, char *argv[])
{
	cout << "Hello world!" << endl;
	int i=0;
	while(true)
	{
		cout << "C++: " << i++ <<endl;
		sleep(1);
	}
}

Result of experiment you can see here https://www.dropbox.com/s/y61ttepmorzpnm2/VID_Bug.mp4?dl=0

On video I've run two applications then I typed command "timedatectl..." and mono application hung. Note that if to use command "hwclock --systohc" instead "timedatectl..." that result is same.
My mono is 4.6.1
Output of uname -a "4.8.8-2-ARCH #1 SMP PREEMPT Thu Nov 17..."

It is real bug, because I'm forced to close real mono application then using native application in order to set time/date then again to run mono application.

When problem will be resolved event me via rombersoft@gmail.com
Comment 2 Brandon White 2017-09-07 20:30:51 UTC
I can confirm that this is resolved in Mono 5.2!