2010/1/16 Němec Alexandr <span dir="ltr">&lt;<a href="mailto:a.nemec@atlas.cz">a.nemec@atlas.cz</a>&gt;</span><br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi all,<br>
somebody posted a suggestion that the socket (when using timeout in the RTSP client) must be set back to blocking. Is this already corrected in the current code release and is it necessary to do so, what are the consequences when the socket is not set back to blocking?<br>
</blockquote><div><br>I wondered the same thing, so I tracked down the change, which seems to have originated from the VLC project in October, 2008:<br>
<br>
<a href="http://mailman.videolan.org/pipermail/vlc-devel/2008-October/051390.html" target="_blank">http://mailman.videolan.org/pipermail/vlc-devel/2008-October/051390.html</a><br>
<br>
Looking at the original patch, it&#39;s pretty clear that the author forgot
to set the socket back to be blocking.  But considering that this issue
has been present for well over a year, I have to wonder whether or not
the RTSPClient even needs to be run on a blocking socket. (Ross, you
know the most about this, so I&#39;d be interested to hear your take on
things).<br>
<br>
FWIW, I haven&#39;t tested this patch yet (been busy), but here&#39;s the
changes you&#39;d need to revert the socket to blocking.  In
GroupsockHelper.h and .cpp:<br>
<br>
Boolean makeSocketBlocking(int sock);<br>
<br>
Boolean makeSocketBlocking(int sock) {<br>
#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)<br>
  unsigned long arg = 0;<br>
  return ioctlsocket(sock, FIONBIO, &amp;arg) == 0;<br>
#elif defined(VXWORKS)<br>
  int arg = 0;<br>
  return ioctl(sock, FIONBIO, (int)&amp;arg) == 0;<br>
#else<br>
  int curFlags = fcntl(sock, F_GETFL, 0);<br>
  return fcntl(sock, F_SETFL, curFlags&amp;(~O_NONBLOCK)) &gt;= 0;<br>
#endif<br>
}<br>
<br>
...and in RTSPClient.cpp,<br>
<br>
fd_set set;<br>
      FD_ZERO(&amp;set);<br>
      timeval tvout = {0,0};<br>
      if (timeout &gt; 0) {<br>
          FD_SET((unsigned)fInputSocketNum, &amp;set);<br>
          tvout.tv_sec = timeout;<br>
          tvout.tv_usec = 0;<br>
          makeSocketNonBlocking(fInputSocketNum);<br>
      }<br>
      if (connect(fInputSocketNum, (struct sockaddr*) &amp;remoteName, sizeof remoteName) != 0) {<br>
          if (envir().getErrno() != EINPROGRESS &amp;&amp; envir().getErrno() != EWOULDBLOCK) {<br>
              envir().setResultErrMsg(&quot;connect() failed: &quot;);<br>
              break;<br>
          }<br>
          if (timeout &gt; 0 &amp;&amp; (select(fInputSocketNum + 1, NULL, &amp;set, NULL, &amp;tvout) &lt;= 0)) {<br>
              envir().setResultErrMsg(&quot;select/connect() failed: &quot;);<br>
              break;<br>
          }<br>
      }<br>
      // If we set our socket to non-blocking, put it back in blocking mode now.<br>
      if( timeout &gt; 0 ){<br>
          makeSocketBlocking(fInputSocketNum);<br>
      }<br><br>I&#39;ll probably get a chance to try these out sometime next week, on both Win32 and embedded linux, so I can vouch for those platforms.  I have no idea if the VXWORKS code is correct (I did review it with a coworker who thought it looked good), and no way of testing that platform. <br>
</div></div>