#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
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" );
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" );
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) ) {
}
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 ) {
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 );
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 {