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 +2/−2
- src/Control/Concurrent/AlarmClock.hs +36/−20
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