--- a/borgend/dreamtime.py Tue Feb 06 08:30:20 2018 +0000 +++ b/borgend/dreamtime.py Tue Feb 06 20:16:59 2018 +0000 @@ -215,10 +215,16 @@ class SleepHandler(Foundation.NSObject): """ Handle wake/sleep notifications """ + # We need to use the actual time.time() to monitor sleep, as + # time.monotonic() many not run during sleep. But time.time() + # may encounter adjustments, so we also use time.monotonic() to + # monitor wake periods. + def init(self): self.__sleeptime=None - self.__slept=0 - self.__epoch=time.monotonic() + self.__dreamtime_last_sleep=0 + self.__monotonic_last_wakeup=time.monotonic() + self.__slept=0 # Only used to store the statistic self.__lock=threading.Lock() self.__callbacks=weakref.WeakKeyDictionary() @@ -227,18 +233,21 @@ @protect_noreturn def handleSleepNotification_(self, aNotification): logger.info("System going to sleep") - now=time.monotonic() with self.__lock: - self.__sleeptime=now + self.__sleeptime=time.time() + now_m=time.monotonic() + self.__dreamtime_last_sleep=(self.__dreamtime_last_sleep+now_m + -self.__monotonic_last_wakeup) callbacks=self.__callbacks.copy() do_callbacks(callbacks, False) @protect_noreturn def handleWakeNotification_(self, aNotification): logger.info("System waking up from sleep") - now=time.monotonic() with self.__lock: if self.__sleeptime: + self.__monotonic_last_wakeup=time.monotonic() + now=time.time() slept=max(0, now-self.__sleeptime) logger.info("Slept %f seconds" % slept) self.__slept=self.__slept+slept @@ -248,7 +257,6 @@ # Return dreamtime def dreamtime_sleeping(self, snapshot=Snapshot()): - sleeping=False with self.__lock: # macOS "sleep" signals / status are complete bollocks: at least # when plugged in, the system is actually sometimes running all @@ -256,11 +264,13 @@ # Therefore, we need our timers to work in a sane manner when # we should be sleeping! if self.__sleeptime is not None: - now_monotonic=self.__sleeptime sleeping=True + now_dreamtime=self.__dreamtime_last_sleep else: - now_monotonic=snapshot.monotonic() - now_dreamtime=max(0, now_monotonic-self.__epoch-self.__slept) + sleeping=False + now=snapshot.monotonic() + now_dreamtime=(self.__dreamtime_last_sleep + +now-self.__monotonic_last_wakeup); return now_dreamtime, sleeping # Weirdo (Py)ObjC naming to stop it form choking up