xref: /freebsd/usr.sbin/ppp/timer.c (revision 17ee9d00bc1ae1e598c38f25826f861e4bc6c3ce)
1 /*
2  *		PPP Timer Processing Module
3  *
4  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5  *
6  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the Internet Initiative Japan, Inc.  The name of the
14  * IIJ may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * $Id:$
21  *
22  *  TODO:
23  */
24 #include "defs.h"
25 #include <sys/time.h>
26 #include <signal.h>
27 #include "timeout.h"
28 
29 void
30 StartTimer(tp)
31 struct pppTimer *tp;
32 {
33   struct pppTimer *t, *pt;
34   u_long ticks = 0;
35 
36   if (tp->state == TIMER_RUNNING) {
37     StopTimer(tp);
38   }
39   if (tp->load == 0) {
40 #ifdef DEBUG
41     logprintf("timer %x has 0 load!\n", tp);
42 #endif
43     return;
44   }
45   pt = NULL;
46   for (t = TimerList; t; t = t->next) {
47 #ifdef DEBUG
48     logprintf("%x(%d):  ticks: %d, rest: %d\n", t, t->state, ticks, t->rest);
49 #endif
50     if (ticks + t->rest >= tp->load)
51       break;
52     ticks += t->rest;
53     pt = t;
54   }
55 
56   tp->state = TIMER_RUNNING;
57   tp->rest = tp->load - ticks;
58 #ifdef DEBUG
59   logprintf("Inserting %x before %x, rest = %d\n", tp, t, tp->rest);
60 #endif
61   /* Insert given *tp just before *t */
62   tp->next = t;
63   if (pt) {
64     pt->next = tp;
65   } else
66     TimerList = tp;
67   if (t)
68     t->rest -= tp->rest;
69 }
70 
71 void
72 StopTimer(tp)
73 struct pppTimer *tp;
74 {
75   struct pppTimer *t, *pt;
76 
77   if (tp->state != TIMER_RUNNING) {
78     tp->next = NULL;
79     return;
80   }
81 
82 #ifdef DEBUG
83   logprintf("StopTimer: %x, next = %x\n", tp, tp->next);
84 #endif
85   pt = NULL;
86   for (t = TimerList; t != tp; t = t->next)
87     pt = t;
88   if (t) {
89     if (pt)
90       pt->next = t->next;
91     else
92       TimerList = t->next;
93     if (t->next)
94       t->next->rest += tp->rest;
95   } else
96     fprintf(stderr, "Oops, timer not found!!\n");
97   tp->next = NULL;
98   tp->state = TIMER_STOPPED;
99 }
100 
101 void
102 TimerService()
103 {
104   struct pppTimer *tp, *exp, *wt;
105 
106   if (tp = TimerList) {
107     tp->rest--;
108     if (tp->rest == 0) {
109       /*
110        * Multiple timers may expires at once. Create list of expired timers.
111        */
112       exp = NULL;
113       do {
114 	tp->state = TIMER_EXPIRED;
115 	wt = tp->next;
116 	tp->enext = exp;
117 	exp = tp;
118 #ifdef DEBUG
119 	logprintf("Add %x to exp\n", tp);
120 #endif
121 	tp = wt;
122       } while (tp && (tp->rest == 0));
123 
124       TimerList = tp;
125 #ifdef DEBUG
126       logprintf("TimerService: next is %x(%d)\n",
127 		TimerList, TimerList? TimerList->rest : 0);
128 #endif
129       /*
130        * Process all expired timers.
131        */
132       while (exp) {
133 #ifdef notdef
134 	StopTimer(exp);
135 #endif
136 	if (exp->func)
137 	  (*exp->func)(exp->arg);
138 	exp = exp->enext;
139       }
140     }
141   }
142 }
143 
144 void
145 ShowTimers()
146 {
147   struct pppTimer *pt;
148 
149   for (pt = TimerList; pt; pt = pt->next)
150     fprintf(stderr, "%x: load = %d, rest = %d\r\n", pt, pt->load, pt->rest);
151 }
152