Hi all,<br><br>I'm trying to run a loop that repeatedly attempts to open a file until it succeeds. The file is a named pipe in nonblocking mode, so the writer can only connect after the reader has connected. (Perhaps there is some way to determine this by stat'ing the pipe, but I don't know it yet.)<br>
<br>Thus I do something like the following:<br><br><span style="font-family:courier new,monospace"> tryUntilNoIOErr $ do </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> performGC</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> -- The reader must connect first, the writer here spins with backoff.</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> PIO.openFd filename PIO.WriteOnly Nothing fileFlags</span><br>
<br>I'm running GC between iterations to try to make sure I get rid of open files. Also, in the "tryUntilNoIOErr" code below I have some debugging messages which indicate that ioeGetHandle reports no handles associated with the exceptions I'm getting back. (If there were handles provided I could close them explicitly.)<br>
<br>In spite of these attempted precautions I'm seeing "too many open files" exceptions in simple benchmarks that should only have a maximum of ONE file open. <br><br>Any hints / pointers?<br><br>Thanks,<br>
-Ryan<br><br><br><span style="font-family:courier new,monospace">mkBackoff :: IO (IO ())</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">mkBackoff = </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> do tref <- newIORef 1</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> return$ do t <- readIORef tref</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> writeIORef tref (min maxwait (2 * t))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> threadDelay t</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> where </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> maxwait = 50 * 1000</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">tryUntilNoIOErr :: IO a -> IO a</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">tryUntilNoIOErr action = mkBackoff >>= loop </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> where </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> loop bkoff = </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> handle (\ (e :: IOException) -> </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> do bkoff </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> BSS.hPutStr stderr$ BSS.pack$ " got IO err: " ++ show e</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> case ioeGetHandle e of </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> Nothing -> BSS.hPutStrLn stderr$ BSS.pack$ " no hndl io err."</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> Just x -> BSS.hPutStrLn stderr$ BSS.pack$ " HNDL on io err!" ++ show x</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> loop bkoff) $ </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> action</span><br style="font-family:courier new,monospace">
<br>