Why does Sockets select() block ???

Why does Sockets select() block ???

Post by Michael St » Thu, 14 Jul 1994 00:23:01



In our department we developed a communication component which was designed
to use sockets as its basic mechanism for interprocess communication.

In the select() system call we encountered serious problems causing
the application to block in unpredictable situations.
This behaviour occurs when trying to multiplex several socket-ports with select(). All sockets
in the fd_set are registered for detecting read-events. After trying to find out why the select()-call
blocks, we came to the conclusion that the implementation of select() itself causes the problems.

This problem arises witch SunOS 4.1.x as well as with SORIX (a realtime UNIX from Siemens).

The only workaround we could think of was to implement a polling
strategy instead of using select(). However, the problem with this approach
is the huge amount of CPU-time wasted for busy-waiting.

Did anybody encounter the same or a similar problem?
What is the best workaround or, even, a solution?
Does this problem occur on other Unix systems than the ones listed above?

Thank you for all your help

--
================================================================================

SIEMENS AG Corporate Research & Development   Michael Stal
Dept. ZFE BT SE 31                            Tel: +49 89 63649380
Otto-Hahn-Ring 6                              Fax: +49 89 63640757


Germany                                    

================================================================================

 
 
 

Why does Sockets select() block ???

Post by Casper H.S. D » Thu, 14 Jul 1994 01:21:49



>In our department we developed a communication component which was designed
>to use sockets as its basic mechanism for interprocess communication.
>In the select() system call we encountered serious problems causing
>the application to block in unpredictable situations.

Select blocks, unless you ask it not to. Many people use several
sockets as input to select and experience no blocking.

What exactly is it you are doing?

Casper

 
 
 

Why does Sockets select() block ???

Post by Martin.Kraem » Thu, 14 Jul 1994 21:06:32


: In our department we developed a communication component which was designed
: to use sockets as its basic mechanism for interprocess communication.

: In the select() system call we encountered serious problems causing
: the application to block in unpredictable situations.
: This behaviour occurs when trying to multiplex several socket-ports with select(). All sockets
: in the fd_set are registered for detecting read-events. After trying to find out why the select()-call
: blocks, we came to the conclusion that the implementation of select() itself causes the problems.

The semantics of socket + connect + select are a bit copmplicated and
it's sure worth to have a look at your specific implementation's man
pages. As a working example, it might be useful to peek at the source
of Mosaic-2.4 (.../libwww2/HTTCP.c):

  /* Now, let's get a socket set up from the server for the data: */      
  *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  /*
   * Make the socket non-blocking, so the connect can be canceled.
   * This means that when we issue the connect we should NOT
   * have to wait for the accept on the other end.
   */
  [...]
    ret = ioctl(*s, FIONBIO, &val);
  [...]

  /*
   * Issue the connect.  Since the server can't do an instantaneous accept
   * and we are non-blocking, this will almost certainly return a negative
   * status.
   */
  status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address));

  /*
   * According to the Sun man page for connect:
   *     EINPROGRESS         The socket is non-blocking and the  con-
   *                         nection cannot be completed immediately.
   *                         It is possible to select(2) for  comple-
   *                         tion  by  selecting the socket for writ-
   *                         ing.
   * According to the Motorola SVR4 man page for connect:
   *     EAGAIN              The socket is non-blocking and the  con-
   *                         nection cannot be completed immediately.
   *                         It is possible to select for  completion
   *                         by  selecting  the  socket  for writing.
   *                         However, this is only  possible  if  the
   *                         socket  STREAMS  module  is  the topmost
   *                         module on  the  protocol  stack  with  a
   *                         write  service  procedure.  This will be
   *                         the normal case.
   */
#ifdef SVR4
  if ((status < 0) && ((errno == EINPROGRESS)||(errno == EAGAIN)))
#else
  if ((status < 0) && (errno == EINPROGRESS))
#endif /* SVR4 */
    {
      [...]
        {
          fd_set writefds;
          int intr;

          FD_ZERO(&writefds);
          FD_SET(*s, &writefds);
#ifdef __hpux
          ret = select(FD_SETSIZE, NULL, (int *)&writefds, NULL, &timeout);
#else
          ret = select(FD_SETSIZE, NULL, &writefds, NULL, &timeout);
#endif
          /*
           * Again according to the Sun and Motorola man page for connect:
           *     EALREADY            The socket is non-blocking and a  previ-
           *                         ous  connection attempt has not yet been
           *                         completed.
           * Thus if the errno is NOT EALREADY we have a real error, and
           * should break out here and return that error.
           * Otherwise if it is EALREADY keep on trying to complete the
           * connection.
           */
          if ((ret < 0)&&(errno != EALREADY)
#ifdef SNI /* BUG in SINIX-D SVR4 */
                       &&(errno != EINPROGRESS)
#endif
      [...]
                                            )

--
#include <std/dsclm.h>       /* SNI SU BS2000 SD124 - Muenchen, W. Germany */

                               ______________
                             /\  _____________\
                             \ \ \__________  /
==============================\ \ \      / / /===============================
 Linux - the U*ix of choice!   \ \ \    / / /  Linux is a * Un*x clone
                                \ \ \  / / /   for 386/486, and it's FREE!!
 Everything you ever wanted,     \ \ \/ / /
 and more, too!                   \ \ \/ /  *** Read comp.os.linux ***
===================================\ \  /====================================
                                    \_\/

 
 
 

Why does Sockets select() block ???

Post by Daniel Garc » Sat, 16 Jul 1994 12:20:46




>: In the select() system call we encountered serious problems causing
>: the application to block in unpredictable situations.
>: This behaviour occurs when trying to multiplex several socket-ports with select(). All sockets
>: in the fd_set are registered for detecting read-events. After trying to find out why the select()-call
>: blocks, we came to the conclusion that the implementation of select() itself causes the problems.

[ Long explanation of setting sockets to non blocking deleted ]

It's actually much easier than michael made it out to be.

Here's a snippit of code:

{
  struct timeval timeout = {0,0};

  /* Set up fd_sets and whatnot */

  select(getdtablesize(),&read_fds, &write_fds, &except_fds, &timeout);

Quote:}

and it won't block - since you give it a timeout of zero seconds and
zero milli(micro?  I dont' have a man page handy)seconds.

Enjoy!

D

(I tried to mail - but my mailing system doesn't quite work right yet, so
 I had to post it - sorry ;)

--

UseLinuxReadMoreThinkALotFightClipperBelieveWritePlayMusicOpenHeartsLiveBreath
LoveThinkFeelListenActReasonWatchLearnRideFlySpeakWinFightRiseSingShoutCryDie
<A HREF=http://www.esu.edu/~kender">My Homepage</A>

 
 
 

1. Re^2: Why does Sockets select() block ???

Thank you very much for the many replies I've received in response to my last
posting. I think, I have to describe the problem in a more detailed manner, cos'
most of the replies assume that we've erroneously used a NULL-pointer as
timeout-parameter for select().
Actually, the code looks similar to the following fragment:

/* the fd_set for reading is prepared anyhow ... */
/* now select is called: */

do {
  retcode = select(max_descrptrs, &readSet, NULL, NULL, &timeout);

timeout is set to NULL if blocking is required. In all other cases
concrete time values are used, e.g.:
struct timeval timeout;
timeout.tv_sec  = any value specifying seconds
timeout.tv_usec = any value specifying u_seconds

In our implementation (SunOS 4.1.3 and Sorix) select() blocks even if it is
not instructed to block forever (i.e. even if (&timeout != NULL) holds).

Thannx a lot for all your help

-- Michael

================================================================================

SIEMENS AG Corporate Research & Development   Michael Stal
Dept. ZFE BT SE 31                            Tel: +49 89 63649380
Otto-Hahn-Ring 6                              Fax: +49 89 63640757


Germany                                    

================================================================================

2. UNIX administrator needed

3. select() behavior for Blocking and non-blocking sockets.

4. Memory leak with 100ns simms?

5. HELP!Blocking select times out on a valid socket!

6. (Q) How can I stop linux over-writing /etc/fstab and /etc/mtab

7. Select in non-blocking sockets

8. SLIP BSD--> solaris

9. select and non-blocking sockets

10. select & non-blocking socket

11. Using select() on non-blocking socket?

12. Problem with select() and non-blocking sockets

13. Confused with non blocking socket, SO_SNDLOWAT and select ...