comparison src/atimer.c @ 27913:81d5641c8b04

(start_atimer): Don't abort when timers are stopped. (append_atimer_lists): New function. (cancel_atimer, stop_other_atimers, run_all_atimers): Handle arbitrary lists of stopped and running atimers.
author Gerd Moellmann <gerd@gnu.org>
date Tue, 29 Feb 2000 13:49:02 +0000
parents cc3d4c12e03b
children 98625ad8a015
comparison
equal deleted inserted replaced
27912:ed26ed5b0afc 27913:81d5641c8b04
69 69
70 /* Function prototypes. */ 70 /* Function prototypes. */
71 71
72 static void set_alarm P_ ((void)); 72 static void set_alarm P_ ((void));
73 static void schedule_atimer P_ ((struct atimer *)); 73 static void schedule_atimer P_ ((struct atimer *));
74 static struct atimer *append_atimer_lists P_ ((struct atimer *,
75 struct atimer *));
74 76
75 77
76 /* Start a new atimer of type TYPE. TIME specifies when the timer is 78 /* Start a new atimer of type TYPE. TIME specifies when the timer is
77 ripe. FN is the function to call when the timer fires. 79 ripe. FN is the function to call when the timer fires.
78 CLIENT_DATA is stored in the client_data member of the atimer 80 CLIENT_DATA is stored in the client_data member of the atimer
98 atimer_callback fn; 100 atimer_callback fn;
99 void *client_data; 101 void *client_data;
100 { 102 {
101 struct atimer *t; 103 struct atimer *t;
102 104
103 /* May not be called when some timers are stopped. */
104 if (stopped_atimers)
105 abort ();
106
107 /* Round TIME up to the next full second if we don't have 105 /* Round TIME up to the next full second if we don't have
108 itimers. */ 106 itimers. */
109 #ifndef HAVE_SETITIMER 107 #ifndef HAVE_SETITIMER
110 if (EMACS_USECS (time) != 0) 108 if (EMACS_USECS (time) != 0)
111 { 109 {
166 164
167 void 165 void
168 cancel_atimer (timer) 166 cancel_atimer (timer)
169 struct atimer *timer; 167 struct atimer *timer;
170 { 168 {
171 struct atimer *t, *prev; 169 int i;
172 struct atimer **list; 170
173
174 BLOCK_ATIMERS; 171 BLOCK_ATIMERS;
175 172
176 /* If we've stopped all other timers except TIMER, we can 173 for (i = 0; i < 2; ++i)
177 just reset the list of active atimers to null. */ 174 {
178 if (stopped_atimers && timer == atimers) 175 struct atimer *t, *prev;
179 { 176 struct atimer **list = i ? &stopped_atimers : &atimers;
180 timer->next = free_atimers; 177
181 free_atimers = timer;
182 atimers = NULL;
183 }
184 else
185 {
186 /* See if TIMER is active or stopped. */ 178 /* See if TIMER is active or stopped. */
187 list = stopped_atimers ? &stopped_atimers : &atimers;
188 for (t = *list, prev = 0; t && t != timer; t = t->next) 179 for (t = *list, prev = 0; t && t != timer; t = t->next)
189 ; 180 ;
190 181
191 /* If it is, take it off the list of its list, and put in on the 182 /* If it is, take it off the its list, and put in on the
192 free-list. We don't bother to arrange for setting a 183 free-list. We don't bother to arrange for setting a
193 different alarm time, since a too early one doesn't hurt. */ 184 different alarm time, since a too early one doesn't hurt. */
194 if (t) 185 if (t)
195 { 186 {
196 if (prev) 187 if (prev)
205 196
206 UNBLOCK_ATIMERS; 197 UNBLOCK_ATIMERS;
207 } 198 }
208 199
209 200
210 /* Stop all timers except timer T. T null means stop all timers. 201 /* Append two lists of atimers LIST1 and LIST2 and return the
211 This function may only be called when all timers are running. Two 202 result list. */
212 calls of this function in a row will lead to an abort. You may not 203
213 call cancel_atimer or start_atimer while timers are stopped. */ 204 static struct atimer *
205 append_atimer_lists (list1, list2)
206 struct atimer *list1, *list2;
207 {
208 if (list1 == NULL)
209 return list2;
210 else if (list2 == NULL)
211 return list1;
212 else
213 {
214 struct atimer *p;
215
216 for (p = list1; p->next; p = p->next)
217 ;
218 p->next = list2;
219 return list1;
220 }
221 }
222
223
224 /* Stop all timers except timer T. T null means stop all timers. */
214 225
215 void 226 void
216 stop_other_atimers (t) 227 stop_other_atimers (t)
217 struct atimer *t; 228 struct atimer *t;
218 { 229 {
219 BLOCK_ATIMERS; 230 BLOCK_ATIMERS;
220 231
221 if (stopped_atimers)
222 abort ();
223
224 if (t) 232 if (t)
225 { 233 {
226 struct atimer *p, *prev; 234 struct atimer *p, *prev;
227 235
228 /* See if T is active. */ 236 /* See if T is active. */
240 else 248 else
241 /* T is not active. Let's handle this like T == 0. */ 249 /* T is not active. Let's handle this like T == 0. */
242 t = NULL; 250 t = NULL;
243 } 251 }
244 252
245 stopped_atimers = atimers; 253 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
246 atimers = t; 254 atimers = t;
247 UNBLOCK_ATIMERS; 255 UNBLOCK_ATIMERS;
248 } 256 }
249 257
250 258
255 run_all_atimers () 263 run_all_atimers ()
256 { 264 {
257 if (stopped_atimers) 265 if (stopped_atimers)
258 { 266 {
259 struct atimer *t = atimers; 267 struct atimer *t = atimers;
268 struct atimer *next;
269
260 BLOCK_ATIMERS; 270 BLOCK_ATIMERS;
261 atimers = stopped_atimers; 271 atimers = stopped_atimers;
262 stopped_atimers = NULL; 272 stopped_atimers = NULL;
263 if (t) 273
264 schedule_atimer (t); 274 while (t)
275 {
276 next = t->next;
277 schedule_atimer (t);
278 t = next;
279 }
280
265 UNBLOCK_ATIMERS; 281 UNBLOCK_ATIMERS;
266 } 282 }
267 } 283 }
268 284
269 285