Unix Programming - How does FD_ISSET() return 0 after returned non-zero?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > April 2006 > How does FD_ISSET() return 0 after returned non-zero?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author How does FD_ISSET() return 0 after returned non-zero?
Alex Vinokur

2006-04-02, 7:40 pm

-------------------------------
FD_ISSET(fd, &fdset)
Returns a non-zero value if the bit for the file descriptor fd is set
in the file descriptor set pointed to by fdset, and 0 otherwise.
-------------------------------

How does FD_ISSET() return 0 after returned non-zero?

Let FD_ISSET(fd, &fdset) be non-zero after _first_ non-sero select
return value.
Should _we_ set FD_ISSET(fd, &fdset) to be zero after performing recv()
via fd?
It seems that otherwise FD_ISSET(fd, &fdset) will be always equal to
non-zero in the next checks of select return value (?).

while (1)
{
if (select (num, &fdset, 0, 0, 0) > 0)
{
if (FD_ISSET(fd, &fdset) > 0)
{
// Do something
// What is FD_ISSET(fd, &fdset)'s value here?
}
} // if (select () ...
} // while (1)


Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Chris McDonald

2006-04-02, 7:41 pm

"Alex Vinokur" <alexvn@users.sourceforge.net> writes:

>-------------------------------
>FD_ISSET(fd, &fdset)
>Returns a non-zero value if the bit for the file descriptor fd is set
>in the file descriptor set pointed to by fdset, and 0 otherwise.
>-------------------------------


>How does FD_ISSET() return 0 after returned non-zero?


>Let FD_ISSET(fd, &fdset) be non-zero after _first_ non-sero select
>return value.
>Should _we_ set FD_ISSET(fd, &fdset) to be zero after performing recv()
>via fd?
>It seems that otherwise FD_ISSET(fd, &fdset) will be always equal to
>non-zero in the next checks of select return value (?).


>while (1)
>{
> if (select (num, &fdset, 0, 0, 0) > 0)
> {
> if (FD_ISSET(fd, &fdset) > 0)
> {
> // Do something
> // What is FD_ISSET(fd, &fdset)'s value here?
> }
> } // if (select () ...
>} // while (1)




You need to call FD_CLR, and FD_SET before *every* call to select().

--
Chris.
Andrei Voropaev

2006-04-02, 7:41 pm

On 2006-03-22, Alex Vinokur <alexvn@users.sourceforge.net> wrote:
[...]
> Let FD_ISSET(fd, &fdset) be non-zero after _first_ non-sero select
> return value.
> Should _we_ set FD_ISSET(fd, &fdset) to be zero after performing recv()
> via fd?
> It seems that otherwise FD_ISSET(fd, &fdset) will be always equal to
> non-zero in the next checks of select return value (?).

[...]

No, this is not needed. The bit is set only if there's data available
(we are talking about read set here right?). So you must call recv and
check the return value of it. Only when connection was closed (or there
was some error), you should set this bit to 0.

--
Minds, like parachutes, function best when open
Alex Vinokur

2006-04-02, 7:41 pm


Andrei Voropaev wrote:
> On 2006-03-22, Alex Vinokur <alexvn@users.sourceforge.net> wrote:
> [...]
> [...]
>
> No, this is not needed. The bit is set only if there's data available
> (we are talking about read set here right?). So you must call recv and
> check the return value of it. Only when connection was closed (or there
> was some error), you should set this bit to 0.
>


How?

Can 'the way to do that' be as follows?

while (1)
{
if (select (num, &fdset, 0, 0, 0) > 0)
{
if (FD_ISSET(fd, &fdset) > 0)
{
// Do something
// -------------------------
FD_CLR (fd, &fdset);
FD_SET (fd, &fdset);
// -------------------------
}
} // if (select () ...

} // while (1)


Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

clayne

2006-04-02, 7:41 pm

Alex Vinokur wrote:
> How?
>
> Can 'the way to do that' be as follows?
>
> while (1)
> {
> if (select (num, &fdset, 0, 0, 0) > 0)
> {
> if (FD_ISSET(fd, &fdset) > 0)


Don't even bother with FD_CLR, FD_SET, etc. unless you absolutely have
to.
Do the following:

fd_set rfds, rfds_m;

FD_ADD(fd_i_care_about, &rfds_m);
FD_ADD(another_fd_i_care_about, &rfds_m);
[etc.]

while (1)
{
rfds = rfds_m;
if (select(hi_water_mark, &rfds, NULL, NULL, NULL) > 0)
{
[etc.]
}
}

It's much more foolproof to just make a master set and copy that to a
temporary fd_set previous to calling select(). It's arguably faster, as
well. Make sure any "master" changes to the fd_set are changed in the
master, since that's always copied to the temporary.

Brian Raiter

2006-04-02, 7:41 pm

> Don't even bother with FD_CLR, FD_SET, etc. unless you absolutely have
> to.
> Do the following:
>
> fd_set rfds, rfds_m;
>
> FD_ADD(fd_i_care_about, &rfds_m);
> FD_ADD(another_fd_i_care_about, &rfds_m);
> [etc.]


But please do bother with FD_ZERO, espeically if those variables are
on the stack.

b
Michael Kerrisk

2006-04-02, 7:41 pm

On 22 Mar 2006 21:24:07 -0800, "clayne" <clayne@anodized.com> wrote:

>Alex Vinokur wrote:
>
>Don't even bother with FD_CLR, FD_SET, etc. unless you absolutely have
>to.
>Do the following:
>
>fd_set rfds, rfds_m;


You must have FD_ZERO(&rfds_m) here.

>FD_ADD(fd_i_care_about, &rfds_m);
>FD_ADD(another_fd_i_care_about, &rfds_m);


I think you mean FD_SET here. There is no such thing as FD_ADD.

Cheers,

Michael
clayne

2006-04-02, 7:41 pm

Sorry, yes.

FD_ZERO(&rfds_m); /* first call, auto var contain trash */
FD_SET(fd, &rfds_m); /* don't know what I was smoking with FD_ADD,
brain drain */

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com