Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: Help on use of DMX_OUT_TAP (II)



James Green wrote:
> On Mon, 2 Jun 2003, Johannes Stezenbach wrote:
> 
> > [Code fragment removed]
> > This can't work. You must use select() or poll() to wait for
> > data to arrive, then read() from the file descriptor which is ready.
> 
> I changed my code to use select() and exactly the same happens. I'm 
> beginning to suspect some bug in the DVB driver code.

Alright, there's indeed a bug in the driver (see below).

>   while (1) {
>     int bytes;
>     fd_set readfds;
> 
>     FD_ZERO(&readfds);
>     FD_SET(video_fd, &readfds);
>     FD_SET(audio_fd, &readfds);
> 
>     int sel = select(MAX(video_fd, audio_fd) + 1, &readfds, NULL, &readfds, NULL);

The exceptfds paramter of select() is not for errors, but for out-of-band data, so it's
useless to specify them here.

>     if (FD_ISSET(video_fd, &readfds)) {
>       /* Video. */
>       bytes = read(video_fd, buf, sizeof(buf));
>       if (bytes < 0) {
> 	fprintf(stderr, "Errno %d: ", errno);
> 	perror("video_fd read");
>       } else {
> 	fprintf(stderr, "Read %d bytes from video_fd.\n", bytes);
>       }
>     } else if (FD_ISSET(audio_fd, &readfds)) {

The 'else' here is wrong. Both fds can be signalled at once. But it's
harmless because the fd will be signalled again in the next iteration.

>       /* Audio. */
>       bytes = read(audio_fd, buf, sizeof(buf));
>       if (bytes < 0) {
> 	fprintf(stderr, "Errno %d: ", errno);
> 	perror("audio_fd read");
>       } else {
> 	fprintf(stderr, "Read %d bytes from audio_fd.\n", bytes);
>       }
>     } else {
>       fprintf(stderr, "Select returned nothing?\n");
>     }
>   }
> }
> 
> and the output is typically:
> 
> Buf size is 512, video_fd=3, audio_fd=4.
> Errno 75: video_fd read: Value too large for defined data type
> Read 512 bytes from audio_fd.
> Read 512 bytes from audio_fd.
> Errno 75: video_fd read: Value too large for defined data type
> Read 512 bytes from audio_fd.

It works if the devices are opened with O_NONBLOCK. And this is
indeed a driver bug. Posix guarantees that if a fd is signalled
as readable be select() or poll(), the next read() will *never* block.
But currently it will block until the read() buffer is completely
filled, unless O_NONBLOCK is specified.

Thanks for uncovering this bug, I will look into it as my time permits.


Regards,
Johannes


-- 
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index