summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Event/KQueue.hsc
diff options
context:
space:
mode:
authorKazu Yamamoto <kazu@iij.ad.jp>2012-12-28 12:48:01 +0900
committerJohan Tibell <johan.tibell@gmail.com>2013-02-11 21:38:06 -0800
commit65309d8c642e7a80285b5b989f567e3537beffb3 (patch)
tree1a92dca53f4829f9e4a8d332763aa5af40c055cb /libraries/base/GHC/Event/KQueue.hsc
parentbedbb20e89526dc6c513a001f59290783fea188e (diff)
downloadhaskell-65309d8c642e7a80285b5b989f567e3537beffb3.tar.gz
Making KQueue.poll similar to EPoll.poll.
Diffstat (limited to 'libraries/base/GHC/Event/KQueue.hsc')
-rw-r--r--libraries/base/GHC/Event/KQueue.hsc28
1 files changed, 18 insertions, 10 deletions
diff --git a/libraries/base/GHC/Event/KQueue.hsc b/libraries/base/GHC/Event/KQueue.hsc
index 4f3febb8c7..09e70841fd 100644
--- a/libraries/base/GHC/Event/KQueue.hsc
+++ b/libraries/base/GHC/Event/KQueue.hsc
@@ -114,17 +114,17 @@ poll :: KQueue
-> Maybe Timeout
-> (Fd -> E.Event -> IO ())
-> IO Int
-poll KQueue{..} mtout f = do
- n <- A.unsafeLoad kqueueEvents $ \evp cap ->
- case mtout of
- Just tout -> withTimeSpec (fromTimeout tout) $
- kevent True kqueueFd nullPtr 0 evp cap
- Nothing -> withTimeSpec (TimeSpec 0 0) $
- kevent False kqueueFd nullPtr 0 evp cap
+poll kq mtimeout f = do
+ let events = kqueueEvents kq
+
+ n <- A.unsafeLoad events $ \es cap -> case mtimeout of
+ Just timeout -> kqueueWait (kqueueFd kq) es cap $ fromTimeout timeout
+ Nothing -> kqueueWaitNonBlock (kqueueFd kq) es cap
+
when (n > 0) $ do
- cap <- A.capacity kqueueEvents
- when (n == cap) $ A.ensureCapacity kqueueEvents (2 * cap)
- A.forM_ kqueueEvents $ \e -> f (fromIntegral (ident e)) (toEvent (filter e))
+ A.forM_ events $ \e -> f (fromIntegral (ident e)) (toEvent (filter e))
+ cap <- A.capacity events
+ when (n == cap) $ A.ensureCapacity events (2 * cap)
return n
------------------------------------------------------------------------
-- FFI binding
@@ -274,6 +274,14 @@ kqueueControl kfd ev = void $
withTimeSpec (TimeSpec 0 0) $ \tp ->
withEvent ev $ \evp -> kevent False kfd evp 1 nullPtr 0 tp
+kqueueWait :: KQueueFd -> Ptr Event -> Int -> TimeSpec -> IO Int
+kqueueWait fd es cap tm =
+ withTimeSpec tm $ kevent True fd nullPtr 0 es cap
+
+kqueueWaitNonBlock :: KQueueFd -> Ptr Event -> Int -> IO Int
+kqueueWaitNonBlock fd es cap =
+ withTimeSpec (TimeSpec 0 0) $ kevent False fd nullPtr 0 es cap
+
-- TODO: We cannot retry on EINTR as the timeout would be wrong.
-- Perhaps we should just return without calling any callbacks.
kevent :: Bool -> KQueueFd -> Ptr Event -> Int -> Ptr Event -> Int -> Ptr TimeSpec