<div dir="ltr"><div>I came up with this implementation below, that  theoretically flush the buffer non blocking </div><div><br></div><div><div><span class="" style="color:rgb(220,50,47)"><br></span></div><div><br></div><div>hPutBufNonBlocking handle ptr count </div><div>  | count == 0 = return 0</div><div>  | count <  0 = error "negative chunk size"</div><div>  | otherwise =</div><div>    wantWritableHandle "hPutBuf" handle $</div><div>      \ h_@Handle__{..} -> bufWriteNonBlocking h_ (castPtr ptr) count False</div><div><br></div><div><br></div><div><br></div><div>bufWriteNonBlocking :: Handle__-> Ptr Word8 -> Int -> Bool -> IO Int</div><div>bufWriteNonBlocking h_@Handle__{..} ptr count can_block =</div><div>  seq count $ do  -- strictness hack</div><div>  old_buf@Buffer{  bufR=w, bufSize=size }  <- readIORef haByteBuffer</div><div>  -- print (size,w, count)</div><div>  old_buf'@Buffer{  bufR=w', bufSize = size' } <- </div><div>        if size - w <= count</div><div>          then   do</div><div>            (written,old_buf') <- Buffered.flushWriteBuffer0 haDevice old_buf</div><div>            writeIORef haByteBuffer old_buf'</div><div>            print (size , written,w, count)</div><div>            print (bufSize old_buf', bufR old_buf')</div><div>            return old_buf'</div><div>          else return old_buf</div><div>            </div><div>  let count'= if size' - w' > count then count else size' - w'</div><div>  writeChunkNonBlocking h_ (castPtr ptr) count'</div><div>  writeIORef haByteBuffer old_buf'{ bufR = w' + count' }</div><div><br></div><div>  return count'</div><div><br></div><div><br></div><div><br></div><div>writeChunkNonBlocking h_@Handle__{..} ptr bytes</div><div>  | Just fd <- cast haDevice  =  RawIO.writeNonBlocking (fd::FD) ptr bytes</div><div>  | otherwise = error "Todo: hPutBuf"</div><div><br></div><div>But:</div></div><div><br></div><div><div><span class="" style="border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213);color:rgb(7,54,66)"><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.IO.BufferedIO.html#flushWriteBuffer0" class="" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)">flushWriteBuffer0</a></span><span style="color:rgb(0,0,0)"> </span><span class="" style="color:rgb(220,50,47)">::</span><span style="color:rgb(0,0,0)"> </span><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.IO.BufferedIO.html#local-1627535594" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)"><span class="" style="color:rgb(95,95,175)">dev</span></a><span style="color:rgb(0,0,0)"> </span><span class="" style="color:rgb(220,50,47)">-></span><span style="color:rgb(0,0,0)"> </span><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.IO.Buffer.html#Buffer" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)"><span class="" style="color:rgb(95,95,175)">Buffer</span></a><span style="color:rgb(0,0,0)"> </span><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.Word.html#Word8" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)"><span class="" style="color:rgb(95,95,175)">Word8</span></a><span style="color:rgb(0,0,0)"> </span><span class="" style="color:rgb(220,50,47)">-></span><span style="color:rgb(0,0,0)"> </span><span class="" style="color:rgb(95,95,175)">IO</span><span style="color:rgb(0,0,0)"> </span><span class="" style="color:rgb(220,50,47)">(</span><span class="" style="color:rgb(95,95,175)">Int</span><span class="" style="color:rgb(220,50,47)">,</span><span style="color:rgb(0,0,0)"> </span><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.IO.Buffer.html#Buffer" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)"><span class="" style="color:rgb(95,95,175)">Buffer</span></a><span style="color:rgb(0,0,0)"> </span><a href="http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.Word.html#Word8" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)"><span class="" style="color:rgb(95,95,175)">Word8</span></a><span class="" style="color:rgb(220,50,47)">)<br></span></div><div><span class="" style="color:rgb(220,50,47)"><pre style="color:rgb(0,0,0)"><span class="" style="color:rgb(138,138,138)">-- | Flush data from the supplied write buffer out to the device</span>
<a name="line-71"></a>  <span class="" style="color:rgb(138,138,138)">-- without blocking.  Returns the number of bytes written and the</span>
<a name="line-72"></a>  <span class="" style="color:rgb(138,138,138)">-- remaining buffer.</span></pre></span></div>should flush  the send buffer as much as possible without waiting for enough available space in the device/receiving side to empty the send buffer<div><br></div><div>but it blocks as well (at least using sockets), and waits until the whole send buffer is emptied, just like ffunshWriteBuffer.</div><div><br></div><div>So it is not possible for the application to know if both buffers are full.  It can be ckecked if the send buffer is full before flushing, but the device buffers and the receiving buffer may be  empty, and the receiving process idle. In the other side, if the buffer is flushed, since it blocks, the send buffer will appear empty after blocking for some time. So the process can do nothing to detect the congestion condition and it will be non responsive to other events.</div><div><br></div><div>Can fusshWriteBuffer0 and hPutBufNonBlocking be fixed?</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-09-17 16:08 GMT+02:00 Alberto G. Corona <span dir="ltr"><<a href="mailto:agocorona@gmail.com" target="_blank">agocorona@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">It could be, since this module is general for any kind of buffered IO<div><br></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">2015-09-17 16:04 GMT+02:00 Brandon Allbery <span dir="ltr"><<a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Sep 17, 2015 at 10:01 AM, Alberto G. Corona <span dir="ltr"><<a href="mailto:agocorona@gmail.com" target="_blank">agocorona@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>since the flush uses <span style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213);color:rgb(7,54,66)"><a href="https://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.IO.BufferedIO.html#flushWriteBuffer" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,232,213)" target="_blank">flushWriteBuffer</a><div style="display:inline-block;width:16px;min-height:16px"> </div>, that</span> blocks,  hPutBuffNonBlocking does the same than hPutBuff and the buffer congestion can not be detected.</div></blockquote></div><br>Hm. I wonder if this is the DynamicLog bug we've been fighting with in xmonad, too. (pipe full -> xmonad locks up, blocked on pipe write)<span><br><div><br></div>-- <br><div><div dir="ltr"><div>brandon s allbery kf8nh                               sine nomine associates</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>                                  <a href="mailto:ballbery@sinenomine.net" target="_blank">ballbery@sinenomine.net</a></div><div>unix, openafs, kerberos, infrastructure, xmonad        <a href="http://sinenomine.net" target="_blank">http://sinenomine.net</a></div></div></div>
</span></div></div>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div>Alberto.</div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Alberto.</div>
</div>