module System.Posix.IO.Select (select, select', select'') where
import System.Posix.IO.Select.Types
import qualified System.Posix.IO.Select.FdSet as FS
import qualified System.Posix.IO.Select.FdSet.Unsafe as FSUNSAFE
import qualified System.Posix.IO.Select.FdSet.Internal as FSI
import Foreign
import Foreign.C.Types
import System.Posix.Types
import Foreign.Ptr
import Foreign.ForeignPtr
import Misc
foreign import ccall "Select/cbits.h xselect"
c_xselect :: Fd -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> IO CInt
select :: FS.FdSet -> FS.FdSet -> FS.FdSet -> Timeout -> IO Result
select rfds wfds efds timeout =
(
case timeout of
Never -> nullForeignPtr
Time timeval -> mallocInitForeignPtr ((flip poke) timeval)
) >>= \timevalp ->
FS.duplicate rfds >>= \(FSI.FdSet rfdsp brfd) ->
FS.duplicate wfds >>= \(FSI.FdSet wfdsp bwfd) ->
FS.duplicate efds >>= \(FSI.FdSet efdsp befd) ->
withForeignPtr rfdsp $ \rfdsp' ->
withForeignPtr wfdsp $ \wfdsp' ->
withForeignPtr efdsp $ \efdsp' ->
withForeignPtr timevalp $ \timevalp' ->
c_xselect (1 + maximum [brfd, bwfd, befd]) rfdsp' wfdsp' efdsp' (castPtr timevalp') >>= \ret ->
return (
if cError ret
then Error
else if cTrue ret
then Ready ret (FSI.FdSet rfdsp brfd) (FSI.FdSet wfdsp bwfd) (FSI.FdSet efdsp befd)
else Timeout
)
select' :: [Fd] -> [Fd] -> [Fd] -> Timeout -> IO (Maybe ([Fd], [Fd], [Fd]))
select' rfds wfds efds timeout =
(
case timeout of
Never -> nullForeignPtr
Time timeval -> mallocInitForeignPtr ((flip poke) timeval)
) >>= \timevalp ->
FS.fromList rfds >>= \rset@(FSI.FdSet rfdsp brfd) ->
FS.fromList wfds >>= \wset@(FSI.FdSet wfdsp bwfd) ->
FS.fromList efds >>= \eset@(FSI.FdSet efdsp befd) ->
withForeignPtr rfdsp $ \rfdsp' ->
withForeignPtr wfdsp $ \wfdsp' ->
withForeignPtr efdsp $ \efdsp' ->
withForeignPtr timevalp $ \timevalp' ->
c_xselect (1 + maximum [brfd, bwfd, befd]) rfdsp' wfdsp' efdsp' (castPtr timevalp') >>= \ret ->
if cError ret
then return Nothing
else FS.inList rfds rset >>= \rfds' ->
FS.inList wfds wset >>= \wfds' ->
FS.inList efds eset >>= \efds' ->
return $ Just (rfds', wfds', efds')
select'' :: [Fd] -> [Fd] -> [Fd] -> Timeout -> IO CInt
select'' rfds wfds efds timeout =
(
case timeout of
Never -> nullForeignPtr
Time timeval -> mallocInitForeignPtr ((flip poke) timeval)
) >>= \timevalp ->
FS.fromList rfds >>= \rset@(FSI.FdSet rfdsp brfd) ->
FS.fromList wfds >>= \wset@(FSI.FdSet wfdsp bwfd) ->
FS.fromList efds >>= \eset@(FSI.FdSet efdsp befd) ->
withForeignPtr rfdsp $ \rfdsp' ->
withForeignPtr wfdsp $ \wfdsp' ->
withForeignPtr efdsp $ \efdsp' ->
withForeignPtr timevalp $ \timevalp' ->
c_xselect (1 + maximum [brfd, bwfd, befd]) rfdsp' wfdsp' efdsp' (castPtr timevalp')