[commit: ghc] ghc-8.4: KQueue: Fix write notification requests being ignored... (d87bb65)
git at git.haskell.org
git at git.haskell.org
Fri Jan 12 21:42:38 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-8.4
Link : http://ghc.haskell.org/trac/ghc/changeset/d87bb656ad49ce591f71d6516b575e0c3e109a49/ghc
>---------------------------------------------------------------
commit d87bb656ad49ce591f71d6516b575e0c3e109a49
Author: Matthias Treydte <mt at waldheinz.de>
Date: Mon Jan 8 10:33:37 2018 -0500
KQueue: Fix write notification requests being ignored...
when read notifications are requested, too (#13903)
Signed-off-by: Matthias Treydte <mt at waldheinz.de>
KQueue: Drop Bits/FiniteBits instances for Filter as they are really
constants whose bits should not be fiddled with
Signed-off-by: Matthias Treydte <mt at waldheinz.de>
Reviewers: austin, hvr, bgamari
Reviewed By: bgamari
Subscribers: gridaphobe, kazu_yamamoto, rwbarton, thomie
GHC Trac Issues: #13903
Differential Revision: https://phabricator.haskell.org/D3692
(cherry picked from commit 6c3eafb35eb7c664963d08a5904faf8c6471218e)
>---------------------------------------------------------------
d87bb656ad49ce591f71d6516b575e0c3e109a49
libraries/base/GHC/Event/KQueue.hsc | 46 +++++++++++++++++--------------------
1 file changed, 21 insertions(+), 25 deletions(-)
diff --git a/libraries/base/GHC/Event/KQueue.hsc b/libraries/base/GHC/Event/KQueue.hsc
index e9c8419..59b5ce1 100644
--- a/libraries/base/GHC/Event/KQueue.hsc
+++ b/libraries/base/GHC/Event/KQueue.hsc
@@ -28,11 +28,13 @@ available = False
import Data.Bits (Bits(..), FiniteBits(..))
import Data.Int
+import Data.Maybe ( catMaybes )
import Data.Word (Word16, Word32)
import Foreign.C.Error (throwErrnoIfMinus1, eINTR, eINVAL,
eNOTSUP, getErrno, throwErrno)
import Foreign.C.Types
import Foreign.Marshal.Alloc (alloca)
+import Foreign.Marshal.Array (withArrayLen)
import Foreign.Ptr (Ptr, nullPtr)
import Foreign.Storable (Storable(..))
import GHC.Base
@@ -85,23 +87,20 @@ delete kq = do
return ()
modifyFd :: KQueue -> Fd -> E.Event -> E.Event -> IO Bool
-modifyFd kq fd oevt nevt
- | nevt == mempty = do
- let !ev = event fd (toFilter oevt) flagDelete noteEOF
- kqueueControl (kqueueFd kq) ev
- | otherwise = do
- let !ev = event fd (toFilter nevt) flagAdd noteEOF
- kqueueControl (kqueueFd kq) ev
-
-toFilter :: E.Event -> Filter
-toFilter evt
- | evt `E.eventIs` E.evtRead = filterRead
- | otherwise = filterWrite
+modifyFd kq fd oevt nevt = kqueueControl (kqueueFd kq) evs
+ where
+ evs
+ | nevt == mempty = toEvents fd (toFilter oevt) flagDelete noteEOF
+ | otherwise = toEvents fd (toFilter nevt) flagAdd noteEOF
+
+toFilter :: E.Event -> [Filter]
+toFilter e = catMaybes [ check E.evtRead filterRead, check E.evtWrite filterWrite ]
+ where
+ check e' f = if e `E.eventIs` e' then Just f else Nothing
modifyFdOnce :: KQueue -> Fd -> E.Event -> IO Bool
-modifyFdOnce kq fd evt = do
- let !ev = event fd (toFilter evt) (flagAdd .|. flagOneshot) noteEOF
- kqueueControl (kqueueFd kq) ev
+modifyFdOnce kq fd evt =
+ kqueueControl (kqueueFd kq) (toEvents fd (toFilter evt) (flagAdd .|. flagOneshot) noteEOF)
poll :: KQueue
-> Maybe Timeout
@@ -140,8 +139,8 @@ data Event = KEvent {
, udata :: {-# UNPACK #-} !(Ptr ())
} deriving Show
-event :: Fd -> Filter -> Flag -> FFlag -> Event
-event fd filt flag fflag = KEvent (fromIntegral fd) filt flag fflag 0 nullPtr
+toEvents :: Fd -> [Filter] -> Flag -> FFlag -> [Event]
+toEvents fd flts flag fflag = map (\filt -> KEvent (fromIntegral fd) filt flag fflag 0 nullPtr) flts
-- | @since 4.3.1.0
instance Storable Event where
@@ -192,7 +191,7 @@ newtype Filter = Filter Int32
#else
newtype Filter = Filter Int16
#endif
- deriving (Bits, FiniteBits, Eq, Num, Show, Storable)
+ deriving (Eq, Num, Show, Storable)
filterRead :: Filter
filterRead = Filter (#const EVFILT_READ)
@@ -222,11 +221,11 @@ instance Storable TimeSpec where
kqueue :: IO KQueueFd
kqueue = KQueueFd `fmap` throwErrnoIfMinus1 "kqueue" c_kqueue
-kqueueControl :: KQueueFd -> Event -> IO Bool
-kqueueControl kfd ev =
+kqueueControl :: KQueueFd -> [Event] -> IO Bool
+kqueueControl kfd evts =
withTimeSpec (TimeSpec 0 0) $ \tp ->
- withEvent ev $ \evp -> do
- res <- kevent False kfd evp 1 nullPtr 0 tp
+ withArrayLen evts $ \evlen evp -> do
+ res <- kevent False kfd evp evlen nullPtr 0 tp
if res == -1
then do
err <- getErrno
@@ -255,9 +254,6 @@ kevent safe k chs chlen evs evlen ts
| safe = c_kevent k chs (fromIntegral chlen) evs (fromIntegral evlen) ts
| otherwise = c_kevent_unsafe k chs (fromIntegral chlen) evs (fromIntegral evlen) ts
-withEvent :: Event -> (Ptr Event -> IO a) -> IO a
-withEvent ev f = alloca $ \ptr -> poke ptr ev >> f ptr
-
withTimeSpec :: TimeSpec -> (Ptr TimeSpec -> IO a) -> IO a
withTimeSpec ts f
| tv_sec ts < 0 = f nullPtr
More information about the ghc-commits
mailing list