|
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 */
|
|
|
|
|