Q: Mac OS X 10.2.1 and select()

0 views
Skip to first unread message

Cédric Pillonel

unread,
Oct 28, 2002, 8:47:58 AM10/28/02
to
Hi,

I have Mac OS X 10.2.1.
I use sockets and I want to use 'select()' to see when data is available on
the socket. This is what I've made:

int serversock = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(serversock , SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
...
bind(serversock , ...);
listen(serversock , 5);
...
int sock = accept(serversock, ...);
// set non-blocking
int flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | FNDELAY);
...

fd_set ready;
FD_ZERO(&ready);
FD_SET(sock, &ready);
select(1, &ready, NULL, NULL, NULL);
read(sock, buf, 1024);
...

The problem is that my thread is always blocked on the 'select()' although
data is available. It seems that 'select()' doesn't see that data is
available on my socket. Has anyone an idea why ?

Thanks.

Cédric Pillonel

Ruud van Gaal

unread,
Oct 28, 2002, 10:08:58 AM10/28/02
to

Hm, seems odd.
On the other hand, you use non-blocking. You could try and use 'int n;
ioctl(sock,FIONREAD,&n);' to see how many bytes are waiting.
Ofcourse that isn't the best in Unix terms, but may help until a real
answer arrives.


Ruud van Gaal
Free car sim: http://www.racer.nl/
Pencil art : http://www.marketgraph.nl/gallery/

Cary Farrier

unread,
Oct 28, 2002, 11:50:17 AM10/28/02
to
in article 1035812880.581025@exnews, Cédric Pillonel at
cedric....@swisscom.com wrote on 10/28/02 7:47 AM:

> select(1, &ready, NULL, NULL, NULL);
> read(sock, buf, 1024);
> ...
>
> The problem is that my thread is always blocked on the 'select()' although
> data is available. It seems that 'select()' doesn't see that data is

I encountered this behavior as well, and resolved it by providing a non-NULL
timeout value with zero field values.

Cary

Rich Seibel

unread,
Oct 28, 2002, 5:53:40 PM10/28/02
to
On Mon, 28 Oct 2002 14:47:58 +0100, Cédric Pillonel
<cedric....@swisscom.com> wrote:
>Hi,
>
>I have Mac OS X 10.2.1.
>I use sockets and I want to use 'select()' to see when data is available on
>the socket. This is what I've made:
>
>int serversock = socket(AF_INET, SOCK_STREAM, 0);
>int optval = 1;
>setsockopt(serversock , SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
>...
>bind(serversock , ...);
>listen(serversock , 5);
>...
>int sock = accept(serversock, ...);
>// set non-blocking
>int flags = fcntl(sock, F_GETFL, 0);
>fcntl(sock, F_SETFL, flags | FNDELAY);
>...
>
>fd_set ready;
>FD_ZERO(&ready);
>FD_SET(sock, &ready);
>select(1, &ready, NULL, NULL, NULL);
--------^
I believe the problem is here. This should be the largest number of bits
in the sets. In this case that should be the value of sock. Try replacing
the '1' with sock.

Rich

>read(sock, buf, 1024);
>...
>
>The problem is that my thread is always blocked on the 'select()' although
>data is available. It seems that 'select()' doesn't see that data is
>available on my socket. Has anyone an idea why ?
>
>Thanks.
>
>Cédric Pillonel
>
>
>


--
--------------------------------------------------------------------
Rich Seibel, Software Engineer (314)579-0066 ext 211
Object Computing, Inc. seib...@ociweb.com
Need ACE training? See http://www.theaceorb.com
--------------------------------------------------------------------

gpa...@apple.com

unread,
Oct 28, 2002, 6:04:59 PM10/28/02
to
"Cédric Pillonel" <cedric....@swisscom.com> writes:
> fd_set ready;
> FD_ZERO(&ready);
> FD_SET(sock, &ready);
> select(1, &ready, NULL, NULL, NULL);
> read(sock, buf, 1024);
> ...
>
> The problem is that my thread is always blocked on the 'select()' although
> data is available. It seems that 'select()' doesn't see that data is
> available on my socket. Has anyone an idea why ?

Try this:
select(sock+1, &ready, NULL, NULL, NULL);

The first argument to select is the number of *bits* in the fd_set to
scan, not the number of *non-zero bits* in the fd_set. Passing nfds=1
means select() will only check the first bit in the fd_set, which
corresponds to descriptor 0. In your case, sock's descriptor is probably
not zero (because descriptors zero, one, and two are usually stdin, stdout,
and stderr), so select() never actually checks for data on your socket.
Passing sock+1 means select() will use bits [0..sock] in the fd_set,
and your socket should be handled correctly.

See `man 2 select` for details.


--
Greg Parker gpa...@apple.com Java & Objective-C

Ruud van Gaal

unread,
Oct 30, 2002, 6:57:36 AM10/30/02
to

The other were right ofcourse; use select(maxFD+1,...).
About the above comment: that changes the whole scheme: with
select(...,timeout=NULL) you wait forever until some fd gets a signal,
but by adding a timeout struct with zero fields you get a select()
that returns immediately. Which is like busy polling.

Cary Farrier

unread,
Oct 30, 2002, 8:56:26 AM10/30/02
to
> On Mon, 28 Oct 2002 16:50:17 GMT, Cary Farrier
> <use_my_l...@mac.com> wrote:
>> I encountered this behavior as well, and resolved it by providing a non-NULL
>> timeout value with zero field values.
>
> but by adding a timeout struct with zero fields you get a select()
> that returns immediately. Which is like busy polling.

This is good information, thanks. The network code is always busy (the game
is an online game) and the polling behavior must be masked by quantity of
data. I'll change that, it should yield a bit of a performance boost.

Cary

Ruud van Gaal

unread,
Oct 30, 2002, 11:02:19 AM10/30/02
to
On Wed, 30 Oct 2002 13:56:26 GMT, Cary Farrier
<use_my_l...@mac.com> wrote:

Perhaps a sleep()-type function can also help (if most of the time
there's network bytes waiting, the select() might not really do you
too much good). Linux has nanosleep(); I don't know about the Mac.

Also, I have at some point on IRIX (SGI) seen a function that only
triggers an FD if a specified NUMBER of bytes are available. So you
can wait until at least a bunch of bytes is available.
On IRIX, it is used in audio programming to notify you when the audio
buffer becomes empty enough (with audio you don't want to be notified
when just 1 byte is free, you want to wait until at least 0.1 sec or
so of audio becomes available before you pump in a new batch of
samples).

I don't know however how they pulled off the trick. Probably an
ioctl() that may not be supported on every fd.

Eric Albert

unread,
Oct 30, 2002, 1:21:08 PM10/30/02
to
In article <3dc001d1....@news.xs4all.nl>,

KILLSP...@marketgraph.nl (Ruud van Gaal) wrote:

> Perhaps a sleep()-type function can also help (if most of the time
> there's network bytes waiting, the select() might not really do you
> too much good). Linux has nanosleep(); I don't know about the Mac.

nanosleep() is supported in 10.1, but there's no prototype for it. If
you add the prototype, it'll work. It's in the headers in 10.2.

-Eric

--
Eric Albert ejal...@stanford.edu
http://rescomp.stanford.edu/~ejalbert/

Folkert van Heusden

unread,
Mar 24, 2003, 2:00:29 PM3/24/03
to
The first parameter must be the highest fd + 1.
So if you have an array of fds x with n elements, do something like:
int h = 0, loop;
for(loop=0; loop<n; loop++)
h = x[loop] > h ? x[loop] : h;

and then:

rc = select(h + 1, ...);

"Cédric Pillonel" <cedric....@swisscom.com> schreef in bericht
news:1035812880.581025@exnews...

Reply all
Reply to author
Forward
0 new messages