[Live-devel] Blocking socket

Jeremy Noring jnoring at logitech.com
Sat Jan 16 14:53:40 PST 2010


2010/1/16 Němec Alexandr <a.nemec at atlas.cz>

> Hi all,
> 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?
>

I wondered the same thing, so I tracked down the change, which seems to have
originated from the VLC project in October, 2008:

http://mailman.videolan.org/pipermail/vlc-devel/2008-October/051390.html

Looking at the original patch, it'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'd be interested to hear your take on things).

FWIW, I haven't tested this patch yet (been busy), but here's the changes
you'd need to revert the socket to blocking.  In GroupsockHelper.h and .cpp:

Boolean makeSocketBlocking(int sock);

Boolean makeSocketBlocking(int sock) {
#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)
  unsigned long arg = 0;
  return ioctlsocket(sock, FIONBIO, &arg) == 0;
#elif defined(VXWORKS)
  int arg = 0;
  return ioctl(sock, FIONBIO, (int)&arg) == 0;
#else
  int curFlags = fcntl(sock, F_GETFL, 0);
  return fcntl(sock, F_SETFL, curFlags&(~O_NONBLOCK)) >= 0;
#endif
}

...and in RTSPClient.cpp,

fd_set set;
      FD_ZERO(&set);
      timeval tvout = {0,0};
      if (timeout > 0) {
          FD_SET((unsigned)fInputSocketNum, &set);
          tvout.tv_sec = timeout;
          tvout.tv_usec = 0;
          makeSocketNonBlocking(fInputSocketNum);
      }
      if (connect(fInputSocketNum, (struct sockaddr*) &remoteName, sizeof
remoteName) != 0) {
          if (envir().getErrno() != EINPROGRESS && envir().getErrno() !=
EWOULDBLOCK) {
              envir().setResultErrMsg("connect() failed: ");
              break;
          }
          if (timeout > 0 && (select(fInputSocketNum + 1, NULL, &set, NULL,
&tvout) <= 0)) {
              envir().setResultErrMsg("select/connect() failed: ");
              break;
          }
      }
      // If we set our socket to non-blocking, put it back in blocking mode
now.
      if( timeout > 0 ){
          makeSocketBlocking(fInputSocketNum);
      }

I'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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100116/2c38cb87/attachment-0001.html>


More information about the live-devel mailing list