You’ve been waiting long enough!
In my previous post on the problems with a polling waitfor, I mentioned that there was a timing window in which we could miss the notification event.
If the path we were looking for was attached in between the stat() and the procmgr_event_notify() call (admittedly a small window) then we would end up waiting the entire timeout duration before noticing that the path had appeared.
Here’s a new version that uses a pulse that closes that hole, by using a pulse as the notification event.
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <time.h> #include <sys/netmgr.h> #include <sys/neutrino.h> #include <sys/procmgr.h> #include <sys/siginfo.h> #define PULSE_CODE_TIMEOUT _PULSE_CODE_MINAVAIL #define PULSE_CODE_PATHSPACE PULSE_CODE_TIMEOUT+1 int main( int argc, char *argv[] ) { struct itimerspec timeout; int timer_id; struct sigevent event; struct stat sbuf; int chid, coid; char *path; struct _pulse pulse; path = argv[1]; memset( &timeout, 0, sizeof(timeout) ); timeout.it_value.tv_sec = atoi(argv[2]); chid = ChannelCreate(0); coid = ConnectAttach( ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0 ); SIGEV_PULSE_INIT( &event, coid, getprio(0), PULSE_CODE_TIMEOUT, 0 ); timer_create( CLOCK_REALTIME, &event, &timer_id ); /* make sure PATHSPACE event has higher priority */ SIGEV_PULSE_INIT( &event, coid, getprio(0)+1, PULSE_CODE_PATHSPACE, 0 ); procmgr_event_notify( PROCMGR_EVENT_PATHSPACE, &event ); /* Check to make sure we don't wait for something already there... */ if ( stat( argv[1], &sbuf ) == 0 ) { printf("Found %s\\n", path ); return EXIT_SUCCESS; } timer_settime( timer_id, 0, &timeout, NULL ); while( MsgReceivePulse( chid, &pulse, sizeof(pulse), NULL ) == 0 ) { switch(pulse.code) { case PULSE_CODE_PATHSPACE: if ( stat( argv[1], &sbuf ) == 0 ) { printf("Found %s\\n", path ); return EXIT_SUCCESS; } break; case PULSE_CODE_TIMEOUT: printf("Timed out waiting for %s\\n", path); return EXIT_FAILURE; default: printf("Unknown pulse code %d waiting for %s\\n", pulse.code, path); return EXIT_FAILURE; } } return EXIT_FAILURE; }
Note that I use a timeout pulse too, and make the timeout pulse have a lower priority than the notification pulse. This is because pulses queue in priority order, and I want to make sure that I receive the path event pulse first.
Cheers,
Colin
If you allow me to be picky ;-) Variable total is unused. Also I assume it’s a http glitch but I assume you meant \n and not !n in the printfs?
Thanks a bunch! Always looking for way to speed startup ;-)
Yes, total is out of there, and the \n was a real pain to add – what does wordpress not understand about preformatted tags???