diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/atimer.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/src/atimer.c b/src/atimer.c index d4cd6ef4801..9dc4f508f8b 100644 --- a/src/atimer.c +++ b/src/atimer.c | |||
| @@ -44,6 +44,11 @@ Boston, MA 02111-1307, USA. */ | |||
| 44 | 44 | ||
| 45 | static struct atimer *free_atimers; | 45 | static struct atimer *free_atimers; |
| 46 | 46 | ||
| 47 | /* List of currently not running timers due to a call to | ||
| 48 | lock_atimer. */ | ||
| 49 | |||
| 50 | static struct atimer *stopped_atimers; | ||
| 51 | |||
| 47 | /* List of active atimers, sorted by expiration time. The timer that | 52 | /* List of active atimers, sorted by expiration time. The timer that |
| 48 | will become ripe next is always at the front of this list. */ | 53 | will become ripe next is always at the front of this list. */ |
| 49 | 54 | ||
| @@ -95,6 +100,10 @@ start_atimer (type, time, fn, client_data) | |||
| 95 | { | 100 | { |
| 96 | struct atimer *t; | 101 | struct atimer *t; |
| 97 | 102 | ||
| 103 | /* May not be called when some timers are stopped. */ | ||
| 104 | if (stopped_atimers) | ||
| 105 | abort (); | ||
| 106 | |||
| 98 | /* Round TIME up to the next full second if we don't have | 107 | /* Round TIME up to the next full second if we don't have |
| 99 | itimers. */ | 108 | itimers. */ |
| 100 | #ifndef HAVE_SETITIMER | 109 | #ifndef HAVE_SETITIMER |
| @@ -161,6 +170,10 @@ cancel_atimer (timer) | |||
| 161 | { | 170 | { |
| 162 | struct atimer *t, *prev; | 171 | struct atimer *t, *prev; |
| 163 | 172 | ||
| 173 | /* May not be called when some timers are stopped. */ | ||
| 174 | if (stopped_atimers) | ||
| 175 | abort (); | ||
| 176 | |||
| 164 | BLOCK_ATIMERS; | 177 | BLOCK_ATIMERS; |
| 165 | 178 | ||
| 166 | /* See if TIMER is active. */ | 179 | /* See if TIMER is active. */ |
| @@ -185,12 +198,70 @@ cancel_atimer (timer) | |||
| 185 | } | 198 | } |
| 186 | 199 | ||
| 187 | 200 | ||
| 201 | /* Stop all timers except timer T. T null means stop all timers. | ||
| 202 | This function may only be called when all timers are running. Two | ||
| 203 | calls of this function in a row will lead to an abort. You may not | ||
| 204 | call cancel_atimer or start_atimer while timers are stopped. */ | ||
| 205 | |||
| 206 | void | ||
| 207 | stop_other_atimers (t) | ||
| 208 | struct atimer *t; | ||
| 209 | { | ||
| 210 | BLOCK_ATIMERS; | ||
| 211 | |||
| 212 | if (stopped_atimers) | ||
| 213 | abort (); | ||
| 214 | |||
| 215 | if (t) | ||
| 216 | { | ||
| 217 | cancel_atimer (t); | ||
| 218 | if (free_atimers != t) | ||
| 219 | abort (); | ||
| 220 | free_atimers = free_atimers->next; | ||
| 221 | t->next = NULL; | ||
| 222 | } | ||
| 223 | |||
| 224 | stopped_atimers = atimers; | ||
| 225 | atimers = t; | ||
| 226 | UNBLOCK_ATIMERS; | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | /* Run all timers again, if some have been stopped with a call to | ||
| 231 | stop_other_atimers. */ | ||
| 232 | |||
| 233 | void | ||
| 234 | run_all_atimers () | ||
| 235 | { | ||
| 236 | if (stopped_atimers) | ||
| 237 | { | ||
| 238 | struct atimer *t = atimers; | ||
| 239 | BLOCK_ATIMERS; | ||
| 240 | atimers = stopped_atimers; | ||
| 241 | stopped_atimers = NULL; | ||
| 242 | if (t) | ||
| 243 | schedule_atimer (t); | ||
| 244 | UNBLOCK_ATIMERS; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | |||
| 249 | /* A version of run_all_timers suitable for a record_unwind_protect. */ | ||
| 250 | |||
| 251 | Lisp_Object | ||
| 252 | unwind_stop_other_atimers (dummy) | ||
| 253 | Lisp_Object dummy; | ||
| 254 | { | ||
| 255 | run_all_atimers (); | ||
| 256 | return Qnil; | ||
| 257 | } | ||
| 258 | |||
| 259 | |||
| 188 | /* Arrange for a SIGALRM to arrive when the next timer is ripe. */ | 260 | /* Arrange for a SIGALRM to arrive when the next timer is ripe. */ |
| 189 | 261 | ||
| 190 | static void | 262 | static void |
| 191 | set_alarm () | 263 | set_alarm () |
| 192 | { | 264 | { |
| 193 | |||
| 194 | #if defined (USG) && !defined (POSIX_SIGNALS) | 265 | #if defined (USG) && !defined (POSIX_SIGNALS) |
| 195 | /* USG systems forget handlers when they are used; | 266 | /* USG systems forget handlers when they are used; |
| 196 | must reestablish each time. */ | 267 | must reestablish each time. */ |