{-# LANGUAGE CPP, ForeignFunctionInterface #-}-- | Block until a read or write operation on a socket would succeed---- On most platforms this uses 'Control.Concurrent.threadWaitRead' or-- 'Conctrol.Concurrent.threadWaitWrite', but on Windows we need to do-- something different. ---- See <http://hackage.haskell.org/trac/ghc/ticket/5797>.moduleNetwork.SSH.Client.LibSSH2.WaitSocket(threadWaitRead,threadWaitWrite)whereimportNetwork.Socket(Socket,fdSocket)importSystem.Posix.Types(Fd(Fd))#ifdef mingw32_HOST_OSimportControl.Concurrent(forkIO,newEmptyMVar,putMVar,takeMVar)importControl.Exception(IOException,throwIO,try)importControl.Exception.Base(mask_)importForeign.C.Error(throwErrnoIfMinus1_)importForeign.C.Types(CInt(CInt))importSystem.IO(hWaitForInput,stdin)#elseimportqualifiedGHC.Conc(threadWaitRead,threadWaitWrite)#endifthreadWaitRead::Socket->IO()threadWaitRead=threadWaitRead_.Fd.fdSocketthreadWaitWrite::Socket->IO()threadWaitWrite=threadWaitWrite_.Fd.fdSocket-- | Block the current thread until data is available to read on the-- given file descriptor (GHC only).---- This will throw an 'IOError' if the file descriptor was closed-- while this thread was blocked. To safely close a file descriptor-- that has been used with 'threadWaitRead', use-- 'GHC.Conc.closeFdWith'.threadWaitRead_::Fd->IO()threadWaitRead_fd#ifdef mingw32_HOST_OS-- We have no IO manager implementing threadWaitRead on Windows.-- fdReady does the right thing, but we have to call it in a-- separate thread, otherwise threadWaitRead won't be interruptible,-- and this only works with -threaded.|threaded=withThread(waitFdfd0)|otherwise=casefdof0->do-- hWaitForInput does work properly, but we can only-- do this for stdin since we know its FD._<-hWaitForInputstdin(-1)return()_->error"threadWaitRead requires -threaded on Windows, or use System.IO.hWaitForInput"#else=GHC.Conc.threadWaitReadfd#endif-- | Block the current thread until data can be written to the-- given file descriptor (GHC only).-- This will throw an 'IOError' if the file descriptor was closed-- while this thread was blocked. To safely close a file descriptor-- that has been used with 'threadWaitWrite', use-- 'GHC.Conc.closeFdWith'.threadWaitWrite_::Fd->IO()threadWaitWrite_fd#ifdef mingw32_HOST_OS|threaded=withThread(waitFdfd1)|otherwise=error"threadWaitWrite requires -threaded on Windows"#else=GHC.Conc.threadWaitWritefd#endif#ifdef mingw32_HOST_OSforeignimportccallunsafe"rtsSupportsBoundThreads"threaded::BoolwithThread::IOa->IOawithThreadio=dom<-newEmptyMVar_<-mask_$forkIO$tryio>>=putMVarmx<-takeMVarmcasexofRighta->returnaLefte->throwIO(e::IOException)-- The last argument can be 1 (true) because this will only be applied to-- sockets waitFd::Fd->CInt->IO()waitFdfdwrite=throwErrnoIfMinus1_"fdReady"$fdReady(fromIntegralfd)writeiNFINITE1whereiNFINITE::CIntiNFINITE=0xFFFFFFFF-- urghforeignimportccallsafe"fdReady"fdReady::CInt-- ^ fd->CInt-- ^ write->CInt-- ^ msecs->CInt-- ^ isSock->IOCInt#endif