packages feed

alarmclock 0.4.0.4 → 0.5.0.0

raw patch · 2 files changed

+38/−22 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Concurrent.AlarmClock: earlierOf :: TimeScale t => t -> t -> t
- Control.Concurrent.AlarmClock: getAbsoluteTime :: TimeScale t => IO t
- Control.Concurrent.AlarmClock: microsecondsDiff :: TimeScale t => t -> t -> Integer

Files

alarmclock.cabal view
@@ -1,5 +1,5 @@ name:                alarmclock-version:             0.4.0.4+version:             0.5.0.0 synopsis:            Wake up and perform an action at a certain time. description:         Wake up and perform an action at a certain time. homepage:            https://bitbucket.org/davecturner/alarmclock@@ -7,7 +7,7 @@ license-file:        LICENSE author:              David Turner maintainer:          dave.c.turner@gmail.com-copyright:           (c) David Turner 2014+copyright:           (c) David Turner 2014-2018 category:            Concurrency build-type:          Simple cabal-version:       >=1.10
src/Control/Concurrent/AlarmClock.hs view
@@ -31,7 +31,7 @@   , setAlarmNow   , isAlarmSet   , isAlarmSetSTM-  , TimeScale(..)+  , TimeScale   , MonotonicTime(..)   ) where @@ -49,6 +49,27 @@                                              diffTimeSpec, getTime,                                              toNanoSecs) +{-| Abstraction that allows for a choice between the UTC timescale and a+monotonic timescale, which differ in their handling of irregularities such as+clock adjustments and leap seconds.++Alarms set using the 'UTCTime' timescale wait for the system clock to pass the+given time before going off, and account for the clock being adjusted+backwards and for (positive) leap seconds while waiting. If the clock is set+forwards, or a negative leap second occurs, then the alarm may go off later+than expected by an amount that is roughly equal to the adjustment. It is+possible to correct for this by setting the alarm again after the adjustment+has occurred.++The 'Monotonic' timescale cannot be so adjusted, which may be more suitable for+some applications.++Note that the timeliness of the alarm going off is very much on a "best effort"+basis, and there are many environmental factors that could cause the alarm to+go off later than expected.++-}+ class TimeScale t where   getAbsoluteTime   :: IO t   microsecondsDiff  :: t -> t -> Integer@@ -59,7 +80,7 @@   earlierOf              = min   microsecondsDiff t1 t2 = ceiling $ (1000000 *) $ diffUTCTime t1 t2 -{-| Representation of system monotonic clock. #-}+{-| Representation of system monotonic clock. -} newtype MonotonicTime = MonotonicTime TimeSpec deriving (Show, Eq, Ord)  instance TimeScale MonotonicTime where@@ -148,7 +169,7 @@ runAlarmClock :: TimeScale t => AlarmClock t -> (t -> IO ()) -> IO () runAlarmClock AlarmClock{..} wakeUpAction = labelMyThread "alarmclock" >> loop   where-  loop = readNextSetting >>= go+  loop = readNextSetting >>= handleNewSetting    readNextSetting = atomically $ readTVar acNewSetting >>= \case     AlarmNotSet    -> retry@@ -158,21 +179,16 @@       writeTVar acIsSet True       return $ Just t -  go Nothing           = return ()-  go (Just wakeUpTime) = wakeNoLaterThan wakeUpTime--  wakeNoLaterThan wakeUpTime = do-    timeoutLength <- microsecondsDiff wakeUpTime <$> getAbsoluteTime-    safeTimeout timeoutLength readNextSetting >>= \case-      Nothing -> actAndContinue-      Just newSetting -> go newSetting--  -- Times out immediately if the duration is nonpositive (unlike 'timeout' which waits forever)-  safeTimeout dt action-    | dt > 0    = timeout dt action-    | otherwise = return Nothing+  handleNewSetting Nothing           = return ()+  handleNewSetting (Just wakeUpTime) = wakeShortlyAfter wakeUpTime -  actAndContinue = do-    atomically $ writeTVar acIsSet False-    wakeUpAction =<< getAbsoluteTime-    loop+  wakeShortlyAfter wakeUpTime = do+    now <- getAbsoluteTime+    let microsecondsTimeout = microsecondsDiff wakeUpTime now+    if 0 < microsecondsTimeout+      then maybe (wakeShortlyAfter wakeUpTime) handleNewSetting+              =<< timeout microsecondsTimeout readNextSetting+      else do+        atomically $ writeTVar acIsSet False+        wakeUpAction now+        loop