Mercurial > emacs
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 |