[vdr] vdr-xine: what's wrong with this piece of code -- threading issue?

Stefan Taferner taferner at kde.org
Fri Mar 25 10:02:30 CET 2005


On Friday 25 March 2005 09:38, Reinhard Nissl wrote:
> Hi,
>
> Stefan Taferner wrote:
> >>I'm facing a deadlock situation, when the below code is modified to
> >>ignore the "r == 0" cases (= original code in vdr-xine-0.7.2):
> >
> > r==0 means that there is no data available. Are you sure you want
> > to block in xread until data is available?
>
> Yes, because there is nothing else to do at that point in time.

Ok.

[...]
> > If you want to wait for data (and keep the non-blocking) you should wait
> > some time (200ms or so). If you are not sure about the cPoller, use the
> > select function with a timeout. Then you get exact error codes and all
> > that.
>
> All I'd like to do is to block until the requested data is ready and "r
> == 0" should just indicate that the FIFO was closed by xine.
>
> But for any reason, "r == 0" happens still without the FIFO beeing
> closed. Can someone tell me, how to handle this situation properly?

The read manpage says: On success, the number of bytes read is 
returned (zero indicates end of file). But you probably already know that.

Here is my version of xread, taken from vdr-xine-0.7.2 with modifications.
But it is an untested version of code I wrote at work (still have no vdr at
hands).


  int cXineRemote::xread(int f, void *b, int n)
  {
    int t = 0;
    void (* const sigPipeHandler)(int) = ::signal(SIGPIPE, SIG_IGN);

    while (t < n)
    {
      
      int r = ::read(f, ((char *)b) + t, n - t);
      
      if (r < 0)
      {
        fprintf(stderr, "::read(%d) failed %d: ", n, errno);
        perror("");

        disconnect();
                
        t = -1;
        break;
      }
      else if (r == 0)
      {
        // fprintf( stderr, "::read zero bytes\n");
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(f, &fds);
        struct timeval tmout;
        tmout.tv_sec = 3600;
        tmout.tv_usec = 0;
        int rc = select(f+1, &fds, 0, 0, &tmout);
        fprintf(stderr, "::select returned %d\n", rc);
      }
      else t += r;
    }

    ::signal(SIGPIPE, sigPipeHandler);
    return t;
  }

--Stefan



More information about the vdr mailing list