FYI, lsof confirms that there are indeed many many open connections to the same FIFO:<br><br>Is there some other way to get at (and clean up) the file descriptor that is left by System.Posix.IO.openFD after it throws an exception? <br>
<br>PingPipes 25115 rrnewton 124r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 125r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 126r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>
PingPipes 25115 rrnewton 127r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 128r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 129r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>
PingPipes 25115 rrnewton 130r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 131r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 132r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>
PingPipes 25115 rrnewton 133r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 134r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 135r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>
PingPipes 25115 rrnewton 136r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 137r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>PingPipes 25115 rrnewton 138r FIFO 8,2 0t0 25166171 /tmp/pipe_9083984821255795683<br>
<br><br><div class="gmail_quote">On Tue, Feb 21, 2012 at 11:13 AM, Ryan Newton <span dir="ltr"><<a href="mailto:rrnewton@gmail.com">rrnewton@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
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>
</blockquote></div><br>