5 Haskell wrapper for select() OS functionality. It's use
6 shouldn't be all that common in a Haskell system that implements
7 IO in such a way that's thread friendly, but still.
10 {-# OPTIONS -#include "cbits/selectFrom.h" #-}
13 hSelect -- :: [Handle]
18 , TimeOut(..) -- type _ = Maybe Int
28 import PosixUtil (fdToInt)
31 This stuff should really be done using HDirect.
36 -- Nothing => wait indefinitely.
37 -- Just x | x >= 0 => block waiting for 'x' micro seconds.
38 -- | otherwise => block waiting for '-x' micro seconds.
41 = ([Handle], [Handle], [Handle])
43 hSelect :: [Handle] -- input/read handles
44 -> [Handle] -- output/write handles
45 -> [Handle] -- exceptional handles
48 hSelect ins outs excps timeout = do
49 ins_ <- mapM getFd ins
50 outs_ <- mapM getFd outs
51 excps_ <- mapM getFd excps
52 (max_in, fds_ins) <- marshallFDs ins_
53 (max_out, fds_outs) <- marshallFDs outs_
54 (max_excp,fds_excps) <- marshallFDs excps_
55 tout <- marshallTimeout timeout
56 let max_fd = max_in `max` max_out `max` max_excp
57 rc <- selectFrom__ fds_ins
62 then constructErrorAndFail "hSelect"
65 -- thunk these so that we only pay unmarshalling costs if demanded.
66 ins_ready = unsafePerformIO (getReadyOnes fds_ins ins_)
67 outs_ready = unsafePerformIO (getReadyOnes fds_outs outs_)
68 excps_ready = unsafePerformIO (getReadyOnes fds_outs outs_)
70 return (ins_ready, outs_ready, excps_ready)
72 getFd :: Handle -> IO (Fd,Handle)
77 foreign import "selectFrom__" unsafe
78 selectFrom__ :: ByteArray Int
85 marshallTimeout :: Maybe Int -> IO Int
86 marshallTimeout Nothing = return (-1)
87 marshallTimeout (Just x) = return (abs x)
89 getReadyOnes :: ByteArray Int -> [(Fd,Handle)] -> IO [Handle]
90 getReadyOnes ba ls = do
96 flg <- is_fd_set ba fi
102 marshallFDs :: [(Fd,Handle)] -> IO (Int, ByteArray Int)
104 ba <- stToIO (newCharArray (0, sizeof_fd_set))
107 fillIn acc (f,_) = do
111 x <- foldM fillIn 0 ls
112 ba <- stToIO (unsafeFreezeByteArray ba)
115 foreign import "is_fd_set__" unsafe
116 is_fd_set :: ByteArray Int -> Int -> IO Int
118 foreign import "fd_zero__" unsafe
119 fd_zero :: MutableByteArray RealWorld Int -> IO ()
121 foreign import "fd_set__" unsafe
122 fd_set :: MutableByteArray RealWorld Int -> Int -> IO ()
124 foreign import "sizeof_fd_set__" unsafe