On Sun, Jun 13, 2010 at 7:16 PM, Ross Finlayson <span dir="ltr"><<a href="mailto:finlayson@live555.com">finlayson@live555.com</a>></span> wrote:<br><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I.e., you should be able to remove the following code from the implementation of "readSocket()" in "groupsock/GroupsockHelper.cpp" (line 265):<br>
<br>
int result = blockUntilReadable(env, socket, timeout);<br>
if (timeout != NULL && result == 0) {<br>
bytesRead = 0;<br>
break;<br>
} else if (result <= 0) {<br>
break;<br>
}<br>
<br>
and I think everything will work OK (only more efficiently!).<br>
<br>
So give this a try. If you run into any problems, let us know. (If not, I'll remove this code from the next release of the software.)</blockquote><div><br>I had read about this on the mailing list, but I was wary to disable entire functions. So I ended up neutering one specific place that called readSocket to have a null timeout; I added a five second timeout:<br>
<br><div style="margin-left: 40px;">Boolean Groupsock::handleRead(unsigned char* buffer, unsigned bufferMaxSize,<br> unsigned& bytesRead,<br> struct sockaddr_in& fromAddress) {<br>
// Read data from the socket, and relay it across any attached tunnels<br> //##### later make this code more general - independent of tunnels<br><br> bytesRead = 0;<br><br> int maxBytesToRead = bufferMaxSize - TunnelEncapsulationTrailerMaxSize;<br>
timeval to;<br> to.tv_sec = 5;<br> to.tv_usec = 0;<br> int numBytes = readSocket(env(), socketNum(),<br> buffer, maxBytesToRead, fromAddress, &to);<br> if (numBytes < 0) {<br> if (DebugLevel >= 0) { // this is a fatal error<br>
env().setResultMsg("Groupsock read failed: ",<br> env().getResultMsg());<br> }<br> return False;<br> }<br></div><br>...and the server no longer hangs. In general, given how the code works with a dedicated worker thread, I think there should _never_ be anything that can potentially block for any substantial amount of time (i.e. all infinite timeout calls should be removed).<br>
<br>On a related note, here's one other hack I had to add to prevent crashing:<br><br><div style="margin-left: 40px;">void RTSPServer::RTSPClientSession::handleAlternativeRequestByte1(u_int8_t requestByte) {<br> // Add this character to our buffer; then try to handle the data that we have buffered so far:<br>
if (fRequestBufferBytesLeft == 0) return;<br> if (fRequestBytesAlreadySeen >= RTSP_BUFFER_SIZE ) return; // hack: don't let us overflow fRequestBuffer, and there's some bug<br> // with sessions containing multiple subsessions, when streaming over<br>
// TCP that causes this to fail miserably.<br> fRequestBuffer[fRequestBytesAlreadySeen] = requestByte;<br> handleRequestBytes(1);<br>}<br></div><br>...I previously reported this. When there are multiple sessions being streamed that contain both audio and video (i.e. multiple subsessions) over TCP, sometimes the server will crash with an access violation by walking off the end of fRequestBuffer. I do not understand the crash; I do know that this code prevents it.<br>
</div></div>