poll-0.0.0.2: src/System/Posix/Poll.hsc
module System.Posix.Poll (
Fd(..),
Event(..),
Events,
inp, pri, out, err, hup, nVal,
) where
#include <poll.h>
import Foreign.C.Types (CShort, )
import Foreign.Storable
(Storable(sizeOf, alignment, peek, poke),
peekByteOff, pokeByteOff, )
import qualified System.Posix.Types as Posix
import Data.Ix (Ix, range, index, inRange, rangeSize, )
import Data.Maybe (fromMaybe, )
import qualified Data.Ix.Enum as IxEnum
import qualified Data.EnumBitSet as EnumSet
data Event
= Other Int
| In
| Pri
| Out
| Err
| Hup
| NVal
deriving (Eq, Ord, Show)
eventFlagSet :: Event -> Events
eventFlagSet cap =
case cap of
Other n -> EnumSet.singletonByPosition n
In -> inp
Pri -> pri
Out -> out
Err -> err
Hup -> hup
NVal -> nVal
{- |
The Enum instance may not be very efficient,
but it should hardly be used, at all.
Better use constants such as 'inp' and set manipulation.
If the binary logarithm is computed by constant unfolding,
performance would be better, but direct set manipulation is still faster.
We implement the 'Enum' instance in this way,
in order to stay independent from the particular Poll definitions,
that may differ between platforms.
-}
instance Enum Event where
fromEnum cap =
case cap of
Other n -> n
_ -> EnumSet.mostSignificantPosition (eventFlagSet cap)
toEnum n =
fromMaybe (Other n) $
lookup (EnumSet.singletonByPosition n) $
map (\ev -> (eventFlagSet ev, ev)) $
In :
Pri :
Out :
Err :
Hup :
NVal :
[]
instance Ix Event where
range = IxEnum.range
index = IxEnum.index
inRange = IxEnum.inRange
rangeSize = IxEnum.rangeSize
{-
pollMask :: PollEvent -> CShort
pollMask PollIn = #{const POLLIN}
pollMask PollPri = #{const POLLPRI}
pollMask PollOut = #{const POLLOUT}
pollMask PollErr = #{const POLLERR}
pollMask PollHup = #{const POLLHUP}
pollMask PollNVal = #{const POLLNVAL}
-}
inp, pri, out, err, hup, nVal :: Events
inp = EnumSet.Cons #{const POLLIN}
pri = EnumSet.Cons #{const POLLPRI}
out = EnumSet.Cons #{const POLLOUT}
err = EnumSet.Cons #{const POLLERR}
hup = EnumSet.Cons #{const POLLHUP}
nVal = EnumSet.Cons #{const POLLNVAL}
type Events = EnumSet.T CShort Event
data Fd = Fd
{ fd :: Posix.Fd
, events :: Events
, rEvents :: Events
}
instance Storable Fd where
sizeOf _ = #size struct pollfd
alignment _ = 4
peek p = do
f <- #{peek struct pollfd, fd} p
e <- #{peek struct pollfd, events} p
r <- #{peek struct pollfd, revents} p
return $ Fd (Posix.Fd f) e r
poke p (Fd (Posix.Fd f) e r) = do
#{poke struct pollfd, fd} p f
#{poke struct pollfd, events} p e
#{poke struct pollfd, revents} p r