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

  • Follow


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

0
Reply alexvn866 (278) 3/22/2006 8:54:29 AM

"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.
0
Reply Chris 3/22/2006 9:06:19 AM


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
0
Reply Andrei 3/22/2006 9:13:52 AM

Andrei Voropaev wrote:
> 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.
>

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

0
Reply Alex 3/22/2006 9:56:38 AM

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.

0
Reply clayne 3/23/2006 5:24:07 AM

> 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
0
Reply Brian 3/23/2006 11:59:46 AM

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

>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;

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
0
Reply Michael 3/23/2006 9:18:19 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 */

0
Reply clayne 3/24/2006 5:20:14 AM

7 Replies
1230 Views

(page loaded in 0.143 seconds)

Similiar Articles:













7/27/2012 1:34:10 PM


Reply: