Posix library ,Concurrent Haskell and Haskell IO sub-system

I use the Posix library since I have to communicate via a pipe with another UNIX process. Therefore I have to use fdRead :: Fd -> ByteCount -> IO (String,ByteCount) The problem is that "fdRead" , as a non Haskell-IO sub-system function, seems to block the entire STG system. The rest of the other threads are blocked too. BTW, "String" stands for non-printable bytes I can be sent for a system, '\0' included ? Alternatives: 1 .- Polling. Sleep and ask. ================================ You have to use the setFdOption fd NonblockingRead True fdReadNonBlockingSTG :: Fd -> Int -> IO (String,ByteCount) fdReadNonBlockingSTG mypipe nobytes = do (string,nobytesread) -> fdRead mypipe nobytes if (nobytesread == -1) then do threadDelay 10000 fdReadNonBlockingSTG mypipe nobytes else return (string,nobytesread) myprogram :: IO () ... setFdOption mypipe NonBlockingRead True (a,b) <- fdReadNonBlockingSTG mypipe 2 ... Problem: As you see, "1000" es an arbitrary constant maybe too short, may be too long and this affects throughput. 2.- Desired approach ======================= Ideally I would like to use the threadWaitRead :: Int -> IO() from Concurrent Haskell as ... -- setFdOption mypipe NonBlockingRead True -- should be called? threadWaitRead (fdToInt mypipe) (string,nobytes) <- fdRead mypipe 2 ... But... QUESTIONS ========== A ) is the GHC-RTS ready to dispatch the signal send by the O.S on a "Posix Fd" and make "threadWaitRead" to run as expected ? The Posix library doc warns: intToFd :: Int -> Fd -- use with care fdToInt :: Fd -> Int -- ditto B) Other approaches, like Handles... Is it possible to convert a Fd into a Handle or bypassing it to the RTS another way ?...

In local.glasgow-haskell-users, you wrote:
I use the Posix library since I have to communicate via a pipe with another UNIX process.
Therefore I have to use fdRead :: Fd -> ByteCount -> IO (String,ByteCount)
Why do you "have to" use an Fd? A regular handle should be sufficient. Where do you get the Fd from? Did you consider lifting the Fd back to a Handle? If you really need to read exactly ByteCount bytes, you could go the hard way and set the handle to unbuffered IO and call hGetChar n times. -- http://www-i2.informatik.rwth-aachen.de/stolz/ *** PGP *** S/MIME rage against the finite state machine

On Thu, 10 Jul 2003, Volker Stolz wrote:
In local.glasgow-haskell-users, you wrote:
I use the Posix library since I have to communicate via a pipe with another UNIX process.
Therefore I have to use fdRead :: Fd -> ByteCount -> IO (String,ByteCount)
Why do you "have to" use an Fd? A regular handle should be sufficient. Where do you get the Fd from?
createPipe :: IO (Fd,Fd) (Unkown alternatives)
Did you consider lifting the Fd back to a Handle?
How ? Only known intToFd :: Int -> Fd fdToInt :: Fd -> Int
If you really need to read exactly ByteCount bytes, you could go the hard way and set the handle to unbuffered IO and call hGetChar n times.
OK. What about ? threadReadWait :: Int -> IO() Should I convert a Handle into a Int ?

On Fri, Jul 11, 2003 at 07:37:06AM +0200, Rafael Martinez Torres wrote:
Why do you "have to" use an Fd? A regular handle should be sufficient. Where do you get the Fd from?
createPipe :: IO (Fd,Fd) (Unkown alternatives)
I suppose you have to pass this descriptor to another process through fork()?
Did you consider lifting the Fd back to a Handle?
How ? Only known intToFd :: Int -> Fd fdToInt :: Fd -> Int
There's System.Posix.IO.fdToHandle :: Fd -> IO Handle
What about ? threadReadWait :: Int -> IO() Should I convert a Handle into a Int ?
Yes, that should work, too, but you won't know how many bytes are available. You could use or adapt one of the *MayBlock-ellipses from Foreign.C.Error together with threadWaitRead, but that's making things even more ugly. Volker -- Volker Stolz * http://www-i2.informatik.rwth-aachen.de/stolz/ * PGP * S/MIME

On Fri, 11 Jul 2003, Volker Stolz wrote:
createPipe :: IO (Fd,Fd) (Unkown alternatives)
I suppose you have to pass this descriptor to another process through fork()?
Rigth. (piper,pipew) <- createPipe mpid <- forkProcess case mpid of Nothing -> do --child nobytes <- fdWrite pipew stringToSend Just pid -> do --parent (string,nobytes) <- fdRead piper stringReceived maxBytes
There's System.Posix.IO.fdToHandle :: Fd -> IO Handle
What about ? threadReadWait :: Int -> IO() Should I convert a Handle into a Int ?
I suppose there is System.Posix.IO.handleToFd :: Handle -> IO (Fd) and then ... (piper,pipew) <- createPipe piperHandle <- fdToHandle(piper) threadWaitRead ( fdToInt(handleToFd(piperHandle)) ) message <- hGetLine piperHandle --or whatever. ...
Yes, that should work, too, but you won't know how many bytes are available. You could use or adapt one of the *MayBlock-ellipses from Foreign.C.Error together with threadWaitRead, but that's making things even more ugly.
Volker
OK. Don't worry. Thank you very much. Very usefull.

On Fri, Jul 11, 2003 at 08:39:54AM +0200, Rafael Martinez Torres wrote:
(piper,pipew) <- createPipe piperHandle <- fdToHandle(piper) threadWaitRead ( fdToInt(handleToFd(piperHandle)) ) message <- hGetLine piperHandle --or whatever.
There's no need to call threadWaitRead, Haskell's RTS will take care of Non-Blocking IO for you. -- "Gemischte Materialien // Früher: Restmüll" Aufschrift auf einem Container, Informatik-Parkplatz http://lambda.foldr.org/~vs/ * PGP * S/MIME
participants (3)
-
Rafael Martinez Torres
-
Volker Stolz
-
Volker Stolz