]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
d7e50217 | 6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. |
1c79356b | 7 | * |
d7e50217 A |
8 | * This file contains Original Code and/or Modifications of Original Code |
9 | * as defined in and that are subject to the Apple Public Source License | |
10 | * Version 2.0 (the 'License'). You may not use this file except in | |
11 | * compliance with the License. Please obtain a copy of the License at | |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
13 | * file. | |
14 | * | |
15 | * The Original Code and all software distributed under the License are | |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
1c79356b A |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
d7e50217 A |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
20 | * Please see the License for the specific language governing rights and | |
21 | * limitations under the License. | |
1c79356b A |
22 | * |
23 | * @APPLE_LICENSE_HEADER_END@ | |
24 | */ | |
25 | /* | |
26 | * Copyright (c) 1990, 1996-1998 Apple Computer, Inc. | |
27 | * All Rights Reserved. | |
28 | */ | |
29 | ||
30 | /* | |
31 | * Timer.c | |
32 | * | |
33 | * From v01.12 06/22/90 mbs | |
34 | * Modified for MP, 1996 by Tuyen Nguyen | |
35 | * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX. | |
36 | */ | |
37 | ||
38 | #include <sys/errno.h> | |
39 | #include <sys/types.h> | |
40 | #include <sys/param.h> | |
41 | #include <machine/spl.h> | |
42 | #include <sys/systm.h> | |
43 | #include <sys/kernel.h> | |
44 | #include <sys/proc.h> | |
45 | #include <sys/filedesc.h> | |
46 | #include <sys/fcntl.h> | |
47 | #include <sys/mbuf.h> | |
48 | #include <sys/socket.h> | |
49 | #include <sys/time.h> | |
50 | ||
51 | #include <netat/sysglue.h> | |
52 | #include <netat/appletalk.h> | |
53 | #include <netat/at_pcb.h> | |
54 | #include <netat/debug.h> | |
55 | #include <netat/adsp.h> | |
56 | #include <netat/adsp_internal.h> | |
57 | ||
58 | /* | |
59 | * TrashSession | |
60 | * | |
61 | * Cleanly abort a session that might be open. Called if probe timer expires, | |
62 | * or from AppleTalk event handler (close or network gone away) | |
63 | * | |
64 | * Only call if the session is active (I.e. not for closed or listeners) | |
65 | * | |
66 | * INPUTS: | |
67 | * session pointer | |
68 | * OUTPUTS: | |
69 | * none | |
70 | */ | |
71 | void TrashSession(sp) /* (CCBPtr sp) */ | |
72 | CCBPtr sp; | |
73 | { | |
74 | int s; | |
75 | ||
76 | ATDISABLE(s, sp->lock); | |
77 | sp->userFlags |= eTearDown; | |
78 | sp->removing = 1; | |
79 | sp->state = sClosed; | |
80 | ATENABLE(s, sp->lock); | |
81 | ||
82 | DoClose(sp, errAborted, 1); | |
83 | } | |
84 | ||
85 | ||
86 | /* | |
87 | * DoTimerElem | |
88 | * | |
89 | * INPUTS: | |
90 | * | |
91 | * OUTPUTS: | |
92 | * | |
93 | */ | |
94 | void DoTimerElem(t) /* (TimerElemPtr t) */ | |
95 | TimerElemPtr t; | |
96 | { | |
97 | CCBPtr sp; | |
98 | int s; | |
99 | ||
100 | sp = (CCBPtr)((Ptr)t - t->type); /* Recover stream pointer for this guy */ | |
101 | ATDISABLE(s, sp->lock); | |
102 | ||
103 | if (t->type == kFlushTimerType) { /* flush write data time just fired */ | |
104 | if (sp->sData) { /* If there's any data, flush it. */ | |
105 | sp->writeFlush = 1; | |
106 | goto send; | |
107 | } | |
108 | } else if (t->type == kRetryTimerType) { | |
109 | if (sp->waitingAck) { | |
110 | ||
111 | sp->waitingAck = 0; | |
112 | sp->sendSeq = sp->firstRtmtSeq; | |
113 | sp->pktSendCnt = 0; | |
114 | sp->resentData = 1; /* Had to resend data */ | |
115 | sp->noXmitFlow = 1; /* Don't incr. max packets. */ | |
116 | ||
117 | if ((sp->pktSendMax /= 2) == 0) /* Back off on max # packets | |
118 | * sent */ | |
119 | sp->pktSendMax = 1; | |
120 | ||
121 | if ((sp->roundTrip *= 2) > sp->probeInterval) | |
122 | sp->roundTrip = sp->probeInterval; | |
123 | sp->rtmtInterval = sp->roundTrip + ((short)2 * | |
124 | (short)sp->deviation); | |
125 | goto send; | |
126 | } | |
127 | } else if (t->type == kAttnTimerType) { | |
128 | if (sp->sapb) { /* Unacknowledged attn pkt */ | |
129 | sp->sendAttnData = 1; | |
130 | goto send; | |
131 | } | |
132 | } else if (t->type == kResetTimerType) { | |
133 | if (sp->frpb) { /* Unacknowledged forward reset */ | |
134 | sp->sendCtl |= B_CTL_FRESET; | |
135 | goto send; | |
136 | } | |
137 | } else if (t->type == kProbeTimerType) { | |
138 | if (sp->state == sOpen || sp->state == sClosing) { | |
139 | if (--sp->probeCntr == 0) { /* Connection died */ | |
140 | ATENABLE(s, sp->lock); | |
141 | TrashSession(sp); | |
142 | return; | |
143 | } else { | |
144 | InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, | |
145 | sp->probeInterval); | |
146 | sp->sendCtl |= B_CTL_PROBE; | |
147 | goto send; | |
148 | } | |
149 | } else if (sp->state == sOpening) { | |
150 | if ((sp->openState == O_STATE_OPENWAIT) || | |
151 | (sp->openState == O_STATE_ESTABLISHED)) | |
152 | { | |
153 | if (--sp->openRetrys == 0) { /* Oops, didn't open */ | |
154 | sp->state = sClosed; | |
155 | ATENABLE(s, sp->lock); | |
156 | DoClose(sp, errOpening, 1); | |
157 | return; | |
158 | } /* open failed */ | |
159 | else /* Send packet again */ | |
160 | { | |
161 | sp->sendCtl |= (sp->openState == O_STATE_OPENWAIT) ? | |
162 | B_CTL_OREQ : B_CTL_OREQACK; | |
163 | goto send; | |
164 | } | |
165 | } /* we're opening */ | |
166 | } | |
167 | } | |
168 | ||
169 | else { | |
170 | dPrintf(D_M_ADSP, D_L_ERROR, ("DoTimerElem:Unknown timer type!\n")); | |
171 | } | |
172 | ||
173 | ATENABLE(s, sp->lock); | |
174 | return; | |
175 | ||
176 | send: | |
177 | ATENABLE(s, sp->lock); | |
178 | CheckSend(sp); | |
179 | } | |
180 | ||
181 | void TimerTick_funnel() | |
182 | { | |
183 | thread_funnel_set(network_flock, TRUE); | |
184 | TimerTick(); | |
185 | thread_funnel_set(network_flock, FALSE); | |
186 | } | |
187 | ||
188 | static StopTimer; | |
189 | ||
190 | /* | |
191 | * TimerTick | |
192 | * | |
193 | * Called 6 times per second | |
194 | * INPUTS: | |
195 | * | |
196 | * OUTPUTS: | |
197 | * | |
198 | */ | |
199 | void TimerTick() /* (void) */ | |
200 | { | |
201 | ||
202 | if (StopTimer) { | |
203 | return; | |
204 | } | |
205 | TimerQueueTick(&adspGlobal.slowTimers); | |
206 | TimerQueueTick(&adspGlobal.fastTimers); | |
207 | timeout(TimerTick_funnel, (caddr_t)0, HZ/6); | |
208 | } | |
209 | ||
210 | void TimerStop() | |
211 | { | |
212 | StopTimer = 1; | |
213 | untimeout(TimerTick_funnel, (caddr_t) 0); | |
214 | } |