summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Announcer.hs50
1 files changed, 30 insertions, 20 deletions
diff --git a/Announcer.hs b/Announcer.hs
index 3928890c..1b6cd631 100644
--- a/Announcer.hs
+++ b/Announcer.hs
@@ -19,6 +19,8 @@ module Announcer
19 , itemStatusNum 19 , itemStatusNum
20 , runAction 20 , runAction
21 , unschedule 21 , unschedule
22 , delayAction
23 , scheduleRel
22 24
23 -- lower level, Announcer.Tox needs these. 25 -- lower level, Announcer.Tox needs these.
24 , scheduleImmediately 26 , scheduleImmediately
@@ -96,17 +98,20 @@ data Announcer = Announcer
96 , commander :: TChan SchedulerCommand 98 , commander :: TChan SchedulerCommand
97 } 99 }
98 100
99-- | Schedules an event to occur long ago at the epoch (which effectively makes
100-- the event happen as soon as possible). Note that the caller will usually
101-- also want to interrupt the 'interrutible' delay so that it finds this item
102-- immediately.
103scheduleImmediately :: Announcer -> AnnounceKey -> ScheduledItem -> STM () 101scheduleImmediately :: Announcer -> AnnounceKey -> ScheduledItem -> STM ()
104scheduleImmediately announcer k item = scheduleAbs announcer k item 0 102scheduleImmediately announcer k item =
103 writeTChan (commander announcer) $ RunActionSTM k item
105 104
106scheduleAbs :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM () 105scheduleAbs :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM ()
107scheduleAbs announcer k item absTime = 106scheduleAbs announcer k item absTime =
108 writeTChan (commander announcer) $ ScheduleAction (k, absTime, item) 107 writeTChan (commander announcer) $ ScheduleAction (k, absTime, item)
109 108
109scheduleRel, delayAction :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM ()
110scheduleRel announcer k item relTime =
111 writeTChan (commander announcer) $ DelayAction (k, relTime, item)
112
113delayAction = scheduleRel
114
110runAction :: Announcer -> IO () -> STM () 115runAction :: Announcer -> IO () -> STM ()
111runAction announcer = writeTChan (commander announcer) . RunAction 116runAction announcer = writeTChan (commander announcer) . RunAction
112 117
@@ -134,13 +139,18 @@ forkAnnouncer = do
134 139
135readTChanTimeout :: TVar Bool -> TChan a -> STM (Maybe a) 140readTChanTimeout :: TVar Bool -> TChan a -> STM (Maybe a)
136readTChanTimeout delay pktChannel = do 141readTChanTimeout delay pktChannel = do
137 -- delay <- registerDelay (toMicroseconds timeout)
138 Just <$> readTChan pktChannel <|> pure Nothing <* (readTVar >=> check) delay 142 Just <$> readTChan pktChannel <|> pure Nothing <* (readTVar >=> check) delay
139 143
140toMicroseconds :: POSIXTime -> Int 144toMicroseconds :: POSIXTime -> Int
141toMicroseconds = round . (* 1000) . (* 1000) 145toMicroseconds = round . (* 1000) . (* 1000)
142 146
143data SchedulerCommand = ShutdownScheduler | ScheduleAction KPS | RunAction (IO ()) | UnscheduleAction AnnounceKey 147data SchedulerCommand
148 = ShutdownScheduler
149 | ScheduleAction KPS -- run an action at an absolute time (todo: use UTCTime)
150 | DelayAction KPS -- run an action at a time relative to the present (todo: use NominalDiffTime)
151 | RunAction (IO ())
152 | RunActionSTM AnnounceKey ScheduledItem
153 | UnscheduleAction AnnounceKey
144 154
145listener :: Announcer -> IO () 155listener :: Announcer -> IO ()
146listener announcer = relisten 156listener announcer = relisten
@@ -166,20 +176,20 @@ listener announcer = relisten
166 Nothing -> do 176 Nothing -> do
167 writeTVar (scheduled announcer) (Schedule queue') 177 writeTVar (scheduled announcer) (Schedule queue')
168 (fmap (>> relisten) (fmap fork (f announcer k now))) 178 (fmap (>> relisten) (fmap fork (f announcer k now)))
169
170 where 179 where
171 modifyScheduled f = modifyTVar (scheduled announcer) (Schedule . f . unSchedule) 180 modifyScheduled f = modifyTVar (scheduled announcer) (Schedule . f . unSchedule)
172 declareInactive = writeTVar (announcerActive announcer) False 181 declareInactive = writeTVar (announcerActive announcer) False
173 handleCommand = 182 handleCommand ShutdownScheduler = atomically declareInactive
174 \case 183 handleCommand cmd = (>> relisten) $
175 ShutdownScheduler -> atomically declareInactive 184 case cmd of
176 RunAction io -> io >> relisten 185 ScheduleAction (k, p, s) -> atomically $ modifyScheduled $ PSQ.insert' k s p
177 UnscheduleAction k -> do 186 UnscheduleAction k -> atomically $ modifyScheduled $ PSQ.delete k
178 atomically $ modifyScheduled $ PSQ.delete k 187 RunActionSTM k (ScheduledItem f) -> do
179 relisten 188 now <- getPOSIXTime
180 ScheduleAction (k, p, s) -> do 189 join (atomically $ f announcer k now)
181 atomically $ modifyScheduled $ PSQ.insert' k s p 190 DelayAction (k, p, s) -> do
182 relisten 191 now <- getPOSIXTime
192 atomically $ modifyScheduled $ PSQ.insert' k s (now + p)
183 193
184announceThread :: Announcer -> IO () 194announceThread :: Announcer -> IO ()
185announceThread announcer = do 195announceThread announcer = do