Address complaints by code scanner
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / siwait.c
index d45efa6..c14c5a9 100644 (file)
 #include "sitransport.h"
 #include       <sys/wait.h>
 
+/*
+       The select timeout is about 300 mu-sec. This is fast enough to add a new
+       outbound connection to the poll list before the other side responds,
+       but slow enough so as not to consume excess CPU when idle.
+*/
+#define SI_SELECT_TIMEOUT 300000
 
 extern int SIwait( struct ginfo_blk *gptr ) {
        int fd;                                                 //  file descriptor for use in this routine 
@@ -65,26 +71,22 @@ extern int SIwait( struct ginfo_blk *gptr ) {
 
        ibuf = (char *) malloc( 2048 );
 
-       gptr->sierr = SI_ERR_SHUTD;
-
        if( gptr->flags & GIF_SHUTDOWN ) {                              //  cannot do if we should shutdown 
-               fprintf( stderr, ">>> wait: shutdown on entry????\n" );
+               free( ibuf );
                return SI_ERROR;                                                        //  so just get out 
        }
 
-       gptr->sierr = SI_ERR_HANDLE;
-
        if( gptr->magicnum != MAGICNUM ) {                              //  if not a valid ginfo block 
-               fprintf( stderr, ">>> wait: bad magic on entry????\n" );
+               rmr_vlog( RMR_VL_CRIT, "SI95: wait: bad global info struct magic number is wrong\n" );
+               free( ibuf );
                return SI_ERROR;
        }
 
-       timeout.tv_sec = 0;
-       timeout.tv_usec = 500000;                               // pop every 500ms to ensure we pick up new outbound connections in list
-
-       do {                                                                    // main wait/process loop 
+       do {                                                                    // spin until a callback says to stop (likely never)
+               timeout.tv_sec = 0;                                     // must be reset on every call!
+               timeout.tv_usec = SI_SELECT_TIMEOUT;
 
-               SIbldpoll( gptr );                                      // build the fdlist for poll 
+               SIbldpoll( gptr );                                      // poll list is trashed on each pop; must rebuild
                pstat = select( gptr->fdcount, &gptr->readfds, &gptr->writefds, &gptr->execpfds, &timeout );
 
                if( (pstat < 0 && errno != EINTR)  ) {
@@ -93,7 +95,8 @@ extern int SIwait( struct ginfo_blk *gptr ) {
                }
 
                if( pstat > 0  &&  (! (gptr->flags & GIF_SHUTDOWN)) ) {
-                       for( tpptr = gptr->tplist; tpptr != NULL; tpptr = nextone ) {
+                       tpptr = gptr->tplist; 
+                       while( tpptr != NULL ) { 
                                nextone = tpptr->next;                          //  prevent issues if we delete the block during loop 
 
                                if( tpptr->fd >= 0 ) {
@@ -113,7 +116,6 @@ extern int SIwait( struct ginfo_blk *gptr ) {
                                                                status = SInewsession( gptr, tpptr );                   // accept connection
                                                        } else  {                                                                                       //  data received on a regular port (we support just tcp now
                                                                status = RECV( fd, gptr->rbuf, MAX_RBUF, 0 );   //  read data 
-                                                               //fprintf( stderr, ">>>>> wait popped status =%d\n", status );
                                                                if( status > 0  &&  ! (tpptr->flags & TPF_DRAIN) ) {
                                                                        if( (cbptr = gptr->cbtab[SI_CB_CDATA].cbrtn) != NULL ) {
                                                                                status = (*cbptr)( gptr->cbtab[SI_CB_CDATA].cbdata, fd, gptr->rbuf, status );
@@ -124,22 +126,22 @@ extern int SIwait( struct ginfo_blk *gptr ) {
                                                                                status = (*cbptr)( gptr->cbtab[SI_CB_DISC].cbdata, tpptr->fd );
                                                                                SIcbstat( gptr, status, SI_CB_DISC );   //  handle status 
                                                                        }
-                                                                       SIterm( gptr, tpptr );
+                                                                       SIterm( gptr, tpptr );                  // close FD and mark block for deletion
                                                                }
                                                        }
                                                }
                                        }
                                }                                                               //  if still good fd 
+
+                               tpptr = nextone;
                        }
                }
        } while( gptr->tplist != NULL && !(gptr->flags & GIF_SHUTDOWN) );
 
        free( ibuf );
        if( gptr->tplist == NULL )                                      //  indicate all fds closed 
-               gptr->sierr = SI_ERR_NOFDS;
 
        if( gptr->flags & GIF_SHUTDOWN ) {                      //  we need to stop for some reason 
-               gptr->sierr = SI_ERR_SHUTD;                             //  indicate error exit status 
                status = SI_ERROR;                                              //  status should indicate to user to die 
                SIshutdown( gptr );                                             //  clean things up 
        } else {