This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Condition.wait timeout fails when system clock changes
Type: Stage:
Components: Library (Lib) Versions: Python 2.4
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: exarkun, hashstat, rhettinger
Priority: normal Keywords:

Created on 2006-12-01 18:45 by hashstat, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (6)
msg30724 - (view) Author: BC (hashstat) Date: 2006-12-01 18:45
If the system clock is adjusted after Condition.wait is called with a timeout, the timeout does not expire as expected.  This appears to be due to the threading.Condition class using the system clock to calculate the timeout expiration without taking system clock changes into account.  Let me illustrate this with an example:


   import threading

   c = threading.Condition()
   c.acquire()
   try:
      ...
      c.wait(3600.0)
      ...
   finally:
      c.release()


Let's say the above snippet is executed at 08:00.  Assuming the condition is never notified, the timeout should expire somewhere close to 09:00.  At 08:30 someone notices that the clock is an hour fast and sets it back to 07:30.  The timeout still expire around 09:00 causing a wait of 2 hours instead of the requested 1 hour.

Now let's say instead that the clock was moved ahead to 09:30 at 08:30.  The timeout would expire immediately after only a 30 minute wait.
msg30725 - (view) Author: Jean-Paul Calderone (exarkun) * (Python committer) Date: 2006-12-01 21:06
Why should it work that way?

c.wait(3600) doesn't say "wait until 0900", it says "wait 60 minutes".

If you want c.waitUntil(9 oclock), maybe that would be a good API addition, but it definitely should be a separate method.
msg30726 - (view) Author: BC (hashstat) Date: 2006-12-01 21:57
Apparently my description wasn't as clear as I thought.  I don't care about the clock times in the example.  They were only used to illustrate the point.  What I do care about is that if a use c.wait(3600) ("wait 60 minutes"), then my thread should wake up in roughly 60 minutes without regard to changes in the system clock.

With the current Condition implementation, no matter what timeout is used, setting the system clock ahead reduces or eliminates the wait while setting the system clock back increases the wait.  So if the clock is set back one hour in the middle of a 1 microsecond wait (c.wait(1)), wait will return in an hour and 1 microsecond.  Is this the way it should work?
msg30727 - (view) Author: BC (hashstat) Date: 2006-12-01 22:35
I submitted patch# 1607149 to add checking for clock variations in the wait method when called with a timeout.
msg30728 - (view) Author: Jean-Paul Calderone (exarkun) * (Python committer) Date: 2006-12-01 22:50
Yes, I misunderstood.  Please disregard my comments. :)
msg30729 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2007-04-11 17:19
I don't think this is the right thing to do.  Detecting clock changes is tricky (all you can do is detect backward movement).  Then, deciding what to do about it also involves a certain amount of guesswork (at how much the time changed and what the user really wants to occur).  Also, changing clocks may affect many parts of the system (log entries being out of order, etc) and it is not entirely clear what the interactions should be with the Condition timeout.  IOW, when the clock changes, you've likely got bigger problems.  Refuse the temptation to guess.
History
Date User Action Args
2022-04-11 14:56:21adminsetgithub: 44293
2006-12-01 18:45:29hashstatcreate