Haskell TimeoutManager使用tryPutMVar不放置任何内容
捕捉源Haskell TimeoutManager使用tryPutMVar不放置任何内容,haskell,haskell-snap-framework,stm,Haskell,Haskell Snap Framework,Stm,捕捉源 ------------------------------------------------------------------------------ --|向TimeoutManager注册新连接。 register::IO()--^超时截止日期为时要运行的操作 --超过。 ->TimeoutManager--^要注册的管理器。 ->IO超时句柄 寄存器killAction tm=do 现在managerRead::TimeoutManager->IO() managerThre
------------------------------------------------------------------------------
--|向TimeoutManager注册新连接。
register::IO()--^超时截止日期为时要运行的操作
--超过。
->TimeoutManager--^要注册的管理器。
->IO超时句柄
寄存器killAction tm=do
现在managerRead::TimeoutManager->IO()
managerThread tm=loop`finally`(readIORef connections>>>=destroyAll)
哪里
--------------------------------------------------------------------------
连接=\u连接tm
getTime=\u getTime tm
不活动=_不活动tm
morePlease=\u morePlease tm
waitABit=threadDelay 5000000
--------------------------------------------------------------------------
循环=do
韦塔比特
句柄([],x))
如果为空句柄
那就做吧
--我们处于非活动状态,请进入睡眠状态,直到获得新线程
writeIORef不活动为True
请来塔克姆瓦尔
否则会
现在!
如果没有要处理的句柄,managerRead
将被takeMVar morePlease
阻止<代码>管理器读取::超时管理器->IO()
managerThread tm=loop`finally`(readIORef connections>>>=destroyAll)
哪里
--------------------------------------------------------------------------
连接=\u连接tm
getTime=\u getTime tm
不活动=_不活动tm
morePlease=\u morePlease tm
waitABit=threadDelay 5000000
--------------------------------------------------------------------------
循环=do
韦塔比特
句柄([],x))
如果为空句柄
那就做吧
--我们处于非活动状态,请进入睡眠状态,直到获得新线程
writeIORef不活动为True
请来塔克姆瓦尔
否则会
现在!
如果没有要处理的句柄,managerRead
将被takeMVar morePlease
阻止<代码>#在irc中#haskell、shachaf和edwardk说MVar()
通常用于阻塞目的#在irc中#haskell、shachaf和edwardk说MVar()
通常用于阻塞目的
------------------------------------------------------------------------------
-- | Register a new connection with the TimeoutManager.
register :: IO () -- ^ action to run when the timeout deadline is
-- exceeded.
-> TimeoutManager -- ^ manager to register with.
-> IO TimeoutHandle
register killAction tm = do
now <- getTime
let !state = Deadline $ now + toEnum defaultTimeout
stateRef <- newIORef state
let !h = TimeoutHandle killAction stateRef getTime
atomicModifyIORef connections $ \x -> (h:x, ())
inact <- readIORef inactivity
when inact $ do
-- wake up manager thread
writeIORef inactivity False
_ <- tryPutMVar morePlease ()
return ()
return h
where
getTime = _getTime tm
inactivity = _inactivity tm
morePlease = _morePlease tm
connections = _connections tm
defaultTimeout = _defaultTimeout tm
managerThread :: TimeoutManager -> IO ()
managerThread tm = loop `finally` (readIORef connections >>= destroyAll)
where
--------------------------------------------------------------------------
connections = _connections tm
getTime = _getTime tm
inactivity = _inactivity tm
morePlease = _morePlease tm
waitABit = threadDelay 5000000
--------------------------------------------------------------------------
loop = do
waitABit
handles <- atomicModifyIORef connections (\x -> ([],x))
if null handles
then do
-- we're inactive, go to sleep until we get new threads
writeIORef inactivity True
takeMVar morePlease
else do
now <- getTime
dlist <- processHandles now handles id
atomicModifyIORef connections (\x -> (dlist x, ()))
loop
--------------------------------------------------------------------------
processHandles !now handles initDlist = go handles initDlist
where
go [] !dlist = return dlist
go (x:xs) !dlist = do
state <- readIORef $ _state x
!dlist' <- case state of
Canceled -> return dlist
Deadline t -> if t <= now
then do
_killAction x
return dlist
else return (dlist . (x:))
go xs dlist'
--------------------------------------------------------------------------
destroyAll = mapM_ diediedie
--------------------------------------------------------------------------
diediedie x = do
state <- readIORef $ _state x
case state of
Canceled -> return ()
_ -> _killAction x