Sathya Raghunathan wrote:
> I opened a named pipe fd in read/nonblocking mode, and then associated a
> stream using fdopen
> 
> int pipe1_fd = open("/tmp/myfirstfifo", open_mode);
> FILE *pipe_fd= fdopen(pipe1_fd,"r");
> 
> First time, the read gets blocked on select with a time out of 20 secs as
> set in the function call(expected behaviour).
> Once there is something in the pipe, select returns and FD_ISSET succeeds.
> 
> But after the first successful read from pipe, the while loop continues and
> the next select always returns 1 instead of blocking again for 20 secs(Note:
> I am not writing any data to the pipe at this time). I am not able to reset
> the fds' value. How can i do that? What went wrong? Is it because i am
> mixing file descriptor and the stream?
> 
> The code is
> 
> main()
> {
> fd_set fds;
> while(1)
> {
> if(isready(pipe_fd1,&fds)==1)
> // there is data to process...
> // read using fscanf(%d%c",&length,&comma) and fread(pipe_fd,buffer,length);
> else
> // there is no data to process. need to block on select
> }
> }
> 
> 
> isready(int fd, fd_set *fds)
> {
> FD_ZERO(fds);
> FD_SET(pipe_fd,fds);
> rc = select(fd+1, fds, NULL, NULL, NULL);
> if rc<0
> return -1
> FD_ISSET(fd,fds)?1:0;
> }

Which mode is the pipe opened up in?  Blocking or non-blocking?  You 
aren't very clear on that.

Your use of select() is likely wrong.  select() only CHECKS for 
readability/writability/etc.  There is NO GUARANTEE that the pipe is 
actually readable between the select() call and the time the pipe is 
attempted to be read.  If the pipe is blocking, you can end up blocking 
during the attempted read.  If the pipe is non-blocking, there might not 
be any data there during the read.  Both scenarios can (and do) result 
in obscure errors.

Don't worry - it took almost 7 years before someone pointed out that 
mistake to me.  Using select() properly is actually much less intuitive 
than the documentation makes it out to be.  Basically - if you are using 
it to poll some state of a socket/pipe/resource thinking a future call 
will succeed based on the output of select(), you are using the function 
incorrectly and the application design is flawed.  Using it incorrectly 
also creates very ugly code while using it correctly creates much more 
elegant code.

-- 
Thomas Hruska
CubicleSoft President
Ph: 517-803-4197

*NEW* MyTaskFocus 1.1
Get on task.  Stay on task.

http://www.CubicleSoft.com/MyTaskFocus/

Reply via email to