/* File: timer.c */ /* ********************************************************************* ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR Revised version of code by J.F. Kurose From the companion website for _Computer Networking: A Top-Down Approach Featuring the Internet_ by J.F. Kurose and K. W. Ross (c) 2001 by Addison Wesley Longman Based on document at (as of 02 July 2002) ********************************************************************* */ /*********************/ /* Timer Functions */ /*********************/ /*------------*/ /* starttimer */ /* *----------------------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ void starttimer(entity_t CorS, /* Which of Client or Server is trying to start a timer? */ float increment) { /* How long should the timer wait before it goes off? */ const char *proc="starttimer"; struct event *q; struct event *evptr; if ((Client != CorS) && (Server != CorS)) { fprintf(stderr, "starttimer(): ERROR timer entity is %d " "but only legal values are %d and %d\n", CorS, Client, Server); } if (TRACE>2) { fprintf(TRACEOUT, "%*sSTART TIMER: starting %s timer at %f\n", INDENT,"", (Client == CorS)?"client":(Server == CorS)?"server":"???", KRtime); } for (q=evlist; q!=NULL; q=q->next) { if ( (q->evtype==TIMER_INTERRUPT && q->eventity==CorS) ) { printf("Warning: attempt to start a #2 timer for %s\n", (Client == CorS)?"the client":(Server == CorS)?"the server" :"an unknown entity"); return; } } /* create future event for when timer goes off */ evptr = malloc(sizeof(struct event)); if (NULL != evptr) { evptr->evtime = KRtime + increment; evptr->evtype = TIMER_INTERRUPT; evptr->eventity = CorS; insertevent(evptr); } else { swerr(proc, 1, "out of memory from malloc()\n"); } } /* starttimer() */ /*-----------*/ /* stoptimer */ /* *-----------------------------------------------------*/ /* called by clientStopTimer() and serverStopTimer() functions to */ /* cancel a previously-started timer */ /*-----------------------------------------------------------------*/ void stoptimer(entity_t CorS) { /* Which of Client or Server is trying to stop timer? */ struct event *q; if (TRACE>2) { fprintf(TRACEOUT, "%*sSTOP TIMER: stopping timer at %f\n",INDENT,"",KRtime); } for (q=evlist; q!=NULL; q=q->next) { if ( (TIMER_INTERRUPT==q->evtype && CorS==q->eventity) ) { /* remove this event */ if (NULL==q->next && NULL==q->prev) { /* remove first and only event on list */ evlist=NULL; } else if (NULL==q->next) { /* end of list - there is one in front */ q->prev->next = NULL; } else if (q==evlist) { /* front of list - there must be event after */ q->next->prev=NULL; evlist = q->next; } else { /* middle of list */ q->next->prev = q->prev; q->prev->next = q->next; } free(q); return; } } printf("Warning: unable to cancel your %s timer. It wasn't running.\n", (Client == CorS)?"client":(Server == CorS)?"server":"???"); } /* stoptimer() */ /*-----------*/ /* checktimer */ /* *-----------------------------------------------------*/ /* check a previously-started timer */ /*-----------------------------------------------------------------*/ int checktimer(entity_t CorS) { /* Which of Client or Server is trying to check timer? */ struct event *q; for (q=evlist; q!=NULL; q=q->next) { if ( (TIMER_INTERRUPT==q->evtype && CorS==q->eventity) ) { return 1; } } return 0; } /* checktimer() */ /* EOF (timer.c) */