diff options
author | Andrew Cady <d@jerkface.net> | 2018-06-22 14:46:40 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2018-06-22 17:41:03 -0400 |
commit | 61f9b9b7c0f9ba3fd9f70520303214ad564ac882 (patch) | |
tree | 5c4b63eee6f56570e0c69bb4267e07f3fb35ffea /Announcer.hs | |
parent | f955aa71a7e57f166300ea02436d1284fc5d1480 (diff) |
The announcer thread will now handle relative times
(The same type is used for both relative and absolute times, which isn't
ideal.)
Diffstat (limited to 'Announcer.hs')
-rw-r--r-- | Announcer.hs | 50 |
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. | ||
103 | scheduleImmediately :: Announcer -> AnnounceKey -> ScheduledItem -> STM () | 101 | scheduleImmediately :: Announcer -> AnnounceKey -> ScheduledItem -> STM () |
104 | scheduleImmediately announcer k item = scheduleAbs announcer k item 0 | 102 | scheduleImmediately announcer k item = |
103 | writeTChan (commander announcer) $ RunActionSTM k item | ||
105 | 104 | ||
106 | scheduleAbs :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM () | 105 | scheduleAbs :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM () |
107 | scheduleAbs announcer k item absTime = | 106 | scheduleAbs announcer k item absTime = |
108 | writeTChan (commander announcer) $ ScheduleAction (k, absTime, item) | 107 | writeTChan (commander announcer) $ ScheduleAction (k, absTime, item) |
109 | 108 | ||
109 | scheduleRel, delayAction :: Announcer -> AnnounceKey -> ScheduledItem -> POSIXTime -> STM () | ||
110 | scheduleRel announcer k item relTime = | ||
111 | writeTChan (commander announcer) $ DelayAction (k, relTime, item) | ||
112 | |||
113 | delayAction = scheduleRel | ||
114 | |||
110 | runAction :: Announcer -> IO () -> STM () | 115 | runAction :: Announcer -> IO () -> STM () |
111 | runAction announcer = writeTChan (commander announcer) . RunAction | 116 | runAction announcer = writeTChan (commander announcer) . RunAction |
112 | 117 | ||
@@ -134,13 +139,18 @@ forkAnnouncer = do | |||
134 | 139 | ||
135 | readTChanTimeout :: TVar Bool -> TChan a -> STM (Maybe a) | 140 | readTChanTimeout :: TVar Bool -> TChan a -> STM (Maybe a) |
136 | readTChanTimeout delay pktChannel = do | 141 | readTChanTimeout 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 | ||
140 | toMicroseconds :: POSIXTime -> Int | 144 | toMicroseconds :: POSIXTime -> Int |
141 | toMicroseconds = round . (* 1000) . (* 1000) | 145 | toMicroseconds = round . (* 1000) . (* 1000) |
142 | 146 | ||
143 | data SchedulerCommand = ShutdownScheduler | ScheduleAction KPS | RunAction (IO ()) | UnscheduleAction AnnounceKey | 147 | data 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 | ||
145 | listener :: Announcer -> IO () | 155 | listener :: Announcer -> IO () |
146 | listener announcer = relisten | 156 | listener 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 | ||
184 | announceThread :: Announcer -> IO () | 194 | announceThread :: Announcer -> IO () |
185 | announceThread announcer = do | 195 | announceThread announcer = do |