On Wed, Feb 17, 2010 at 3:54 PM, Jeremy Shaw <span dir="ltr">&lt;<a href="mailto:jeremy@n-heptane.com">jeremy@n-heptane.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On Wed, Feb 17, 2010 at 1:27 PM, Bardur Arantsson <span dir="ltr">&lt;<a href="mailto:spam@scientician.net" target="_blank">spam@scientician.net</a>&gt;</span> wrote:<br></div><div class="gmail_quote"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
(Obviously, if people are using sendfile with something other than happstack,<br>
it does not help them, but it  sounds like trying to fix things in<br>
</blockquote>
&gt; sendfile is misguided anyway.)<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
</blockquote>
<br></div>
How so? As a user I expect sendfile to work and not semi-randomly block threads indefinitely.<br>
<br></blockquote><div><br></div></div><div>Because it only addresses *one* case when this type of blocking can happen.</div><div><br></div><div>Shouldn&#39;t hPut and friends also block indefinitely since they also use threadWaitWrite? If so, what good is just fixing sendfile, when all other network I/O will still block indefinitely?</div>

<div><br></div><div>If things are &#39;fixed&#39; at a higher-level, by using SO_KEEPALIVE, then does sendfile really need a hack to deal with it?</div><div><br></div></div></blockquote><div><br></div><div>I think I understand the SO_KEEPALIVE + SO_ERROR solution, and that does not really fix things either.</div>
<div><br></div><div>Setting SO_KEEPALIVE by itself does not cause the write select() to behave any differently. What it does do is cause the TCP stack to eventually send and empty packet to the remote host and hopefully get a response back. The response might be an error, or it might just be an ACK. But either way, I believe it is intended to cause the read select() to wakeup. But, in the case that started this discussion, we are already getting this information. So this won&#39;t help with that at all.</div>
<div><br></div><div>The second part of the solution is to poll SO_ERROR to determine if something went wrong. This is an alternative to doing a read() on the socket and see if it returns 0 bytes. It is a nice alternative *because* it does not require a read(). However, it is still problematic. When you poll SO_ERROR, it will clear the error value, so there is a potential race condition if multiple threads are doing it.</div>
<div><br></div><div>In happstack, we fork a new thread to handle each incoming connection. So at first it seems like we could just fork a second thread that polls the SO_ERROR option on the socket and kills the first thread if an error happens. Unfortunately, it is not that simple. The first thread might fork another thread that is actually doing the threadWaitWrite. Killing the parent thread will not kill that child thread.</div>
<div><br></div><div>So, at present, I don&#39;t see a solution that is going to fix the problem in the rest of the IO code. There are multiple ways to hack only sendfile.. but that is only one place this error can happen.</div>
<div><br></div><div>If this error truly never happens with hPut, then we should figure out why. If there is a solution that works for write() it should work for sendfile(), because the real issue is with the select() call anyway..</div>
<div><br></div><div>- jeremy</div><div><br></div></div>