summaryrefslogtreecommitdiff
path: root/InterruptibleDelay.hs
diff options
context:
space:
mode:
Diffstat (limited to 'InterruptibleDelay.hs')
-rw-r--r--InterruptibleDelay.hs41
1 files changed, 41 insertions, 0 deletions
diff --git a/InterruptibleDelay.hs b/InterruptibleDelay.hs
new file mode 100644
index 00000000..d59ec8ef
--- /dev/null
+++ b/InterruptibleDelay.hs
@@ -0,0 +1,41 @@
1module InterruptibleDelay where
2
3import Control.Concurrent
4import Control.Monad
5import Control.Exception ({-evaluate,-}handle,ErrorCall(..))
6import Data.Time.Clock (NominalDiffTime)
7
8type Microseconds = Int
9
10microseconds :: NominalDiffTime -> Microseconds
11microseconds d = round $ 1000000 * d
12
13data InterruptibleDelay = InterruptibleDelay
14 { delayThread :: MVar ThreadId
15 }
16
17interruptibleDelay :: IO InterruptibleDelay
18interruptibleDelay = do
19 fmap InterruptibleDelay newEmptyMVar
20
21startDelay :: InterruptibleDelay -> Microseconds -> IO Bool
22startDelay d interval = do
23 thread <- myThreadId
24 handle (\(ErrorCall _)-> do
25 debugNoise $ "delay interrupted"
26 return False) $ do
27 putMVar (delayThread d) thread
28 threadDelay interval
29 void $ takeMVar (delayThread d)
30 return True
31
32 where debugNoise str = return ()
33
34
35interruptDelay :: InterruptibleDelay -> IO ()
36interruptDelay d = do
37 mthread <- do
38 tryTakeMVar (delayThread d)
39 flip (maybe $ return ()) mthread $ \thread -> do
40 throwTo thread (ErrorCall "Interrupted delay")
41