diff options
author | jim@bo <jim@bo> | 2018-06-21 23:12:29 -0400 |
---|---|---|
committer | jim@bo <jim@bo> | 2018-06-21 23:13:31 -0400 |
commit | e8446341d0dbe9b466571fa10875141ed22fbb47 (patch) | |
tree | c0f4ea06175d72156ef02f652024afc767feba75 /PingMachine.hs | |
parent | 7f8d1a5581af33749e0218815e62cc641ef8b64c (diff) |
NetCrypto IdleEvents,TimeOuts
Diffstat (limited to 'PingMachine.hs')
-rw-r--r-- | PingMachine.hs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/PingMachine.hs b/PingMachine.hs index 5cd70f95..4a1cb008 100644 --- a/PingMachine.hs +++ b/PingMachine.hs | |||
@@ -1,6 +1,8 @@ | |||
1 | {-# LANGUAGE CPP #-} | 1 | {-# LANGUAGE CPP #-} |
2 | {-# LANGUAGE TupleSections #-} | ||
2 | module PingMachine where | 3 | module PingMachine where |
3 | 4 | ||
5 | import Control.Applicative | ||
4 | import Control.Monad | 6 | import Control.Monad |
5 | import Data.Function | 7 | import Data.Function |
6 | #ifdef THREAD_DEBUG | 8 | #ifdef THREAD_DEBUG |
@@ -89,6 +91,52 @@ forkPingMachine label idle timeout = do | |||
89 | , pingStarted = started | 91 | , pingStarted = started |
90 | } | 92 | } |
91 | 93 | ||
94 | -- | like 'forkPingMachine' but the timeout and idle parameters can be changed dynamically | ||
95 | -- Unlike 'forkPingMachine', 'forkPingMachineDynamic' always launches a thread | ||
96 | -- regardless of idle value. | ||
97 | forkPingMachineDynamic | ||
98 | :: String | ||
99 | -> TVar PingInterval -- ^ Milliseconds of idle before a ping is considered necessary. | ||
100 | -> TVar TimeOut -- ^ Milliseconds after 'PingIdle' before we signal 'PingTimeOut'. | ||
101 | -> IO PingMachine | ||
102 | forkPingMachineDynamic label idleV timeoutV = do | ||
103 | d <- interruptibleDelay | ||
104 | flag <- atomically $ newTVar False | ||
105 | canceled <- atomically $ newTVar False | ||
106 | event <- atomically newEmptyTMVar | ||
107 | started <- atomically $ newEmptyTMVar | ||
108 | void . forkIO $ do | ||
109 | myThreadId >>= flip labelThread ("Ping." ++ label) -- ("ping.watchdog") | ||
110 | (>>=) (atomically (readTMVar started)) $ flip when $ do | ||
111 | fix $ \loop -> do | ||
112 | atomically $ writeTVar flag False | ||
113 | (idle,timeout) <- atomically $ (,) <$> readTVar idleV <*> readTVar timeoutV | ||
114 | fin <- startDelay d (1000*idle) | ||
115 | (>>=) (atomically (readTMVar started)) $ flip when $ do | ||
116 | if (not fin) then loop | ||
117 | else do | ||
118 | -- Idle event | ||
119 | atomically $ do | ||
120 | tryTakeTMVar event | ||
121 | putTMVar event PingIdle | ||
122 | writeTVar flag True | ||
123 | fin <- startDelay d (1000*timeout) | ||
124 | (>>=) (atomically (readTMVar started)) $ flip when $ do | ||
125 | me <- myThreadId | ||
126 | if (not fin) then loop | ||
127 | else do | ||
128 | -- Timeout event | ||
129 | atomically $ do | ||
130 | tryTakeTMVar event | ||
131 | writeTVar flag False | ||
132 | putTMVar event PingTimeOut | ||
133 | return PingMachine | ||
134 | { pingFlag = flag | ||
135 | , pingInterruptible = d | ||
136 | , pingEvent = event | ||
137 | , pingStarted = started | ||
138 | } | ||
139 | |||
92 | -- | Terminate the watchdog thread. Call this upon connection close. | 140 | -- | Terminate the watchdog thread. Call this upon connection close. |
93 | -- | 141 | -- |
94 | -- You should ensure no threads are waiting on 'pingWait' because there is no | 142 | -- You should ensure no threads are waiting on 'pingWait' because there is no |