#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/sched.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/lock.h>
Go to the source code of this file.
Defines | |
#define | DEBUG(a) |
#define | SOONER(a, b) |
Functions | |
sched_context * | sched_context_create (void) |
New schedule context. | |
void | sched_context_destroy (struct sched_context *con) |
destroys a schedule context | |
int | ast_sched_wait (struct sched_context *con) |
Determines number of seconds until the next outstanding event to take place. | |
int | ast_sched_add (struct sched_context *con, int when, ast_sched_cb callback, void *data) |
Adds a scheduled event. | |
int | ast_sched_del (struct sched_context *con, int id) |
Deletes a scheduled event. | |
void | ast_sched_dump (struct sched_context *con) |
Dumps the scheduler contents. | |
int | ast_sched_runq (struct sched_context *con) |
Runs the queue. |
|
|
|
Value: (((b).tv_sec > (a).tv_sec) || \ (((b).tv_sec == (a).tv_sec) && ((b).tv_usec > (a).tv_usec))) Definition at line 32 of file sched.c. Referenced by ast_sched_runq(). |
|
Adds a scheduled event.
Definition at line 232 of file sched.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, sched::callback, sched::data, DEBUG, sched_context::eventcnt, sched::id, sched_context::lock, LOG_DEBUG, LOG_NOTICE, sched::resched, and sched::when. 00233 { 00234 /* 00235 * Schedule callback(data) to happen when ms into the future 00236 */ 00237 struct sched *tmp; 00238 int res = -1; 00239 DEBUG(ast_log(LOG_DEBUG, "ast_sched_add()\n")); 00240 if (!when) { 00241 ast_log(LOG_NOTICE, "Scheduled event in 0 ms?\n"); 00242 return -1; 00243 } 00244 ast_mutex_lock(&con->lock); 00245 if ((tmp = sched_alloc(con))) { 00246 tmp->id = con->eventcnt++; 00247 tmp->callback = callback; 00248 tmp->data = data; 00249 tmp->resched = when; 00250 tmp->when.tv_sec = 0; 00251 tmp->when.tv_usec = 0; 00252 if (sched_settime(&tmp->when, when)) { 00253 sched_release(con, tmp); 00254 } else { 00255 schedule(con, tmp); 00256 res = tmp->id; 00257 } 00258 } 00259 ast_mutex_unlock(&con->lock); 00260 return res; 00261 }
|
|
Deletes a scheduled event.
Definition at line 263 of file sched.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, CRASH, DEBUG, sched_context::lock, LOG_DEBUG, LOG_NOTICE, sched::next, sched_context::schedcnt, and sched_context::schedq. Referenced by ast_closestream(). 00264 { 00265 /* 00266 * Delete the schedule entry with number 00267 * "id". It's nearly impossible that there 00268 * would be two or more in the list with that 00269 * id. 00270 */ 00271 struct sched *last=NULL, *s; 00272 DEBUG(ast_log(LOG_DEBUG, "ast_sched_del()\n")); 00273 ast_mutex_lock(&con->lock); 00274 s = con->schedq; 00275 while(s) { 00276 if (s->id == id) { 00277 if (last) 00278 last->next = s->next; 00279 else 00280 con->schedq = s->next; 00281 con->schedcnt--; 00282 sched_release(con, s); 00283 break; 00284 } 00285 last = s; 00286 s = s->next; 00287 } 00288 ast_mutex_unlock(&con->lock); 00289 if (!s) { 00290 ast_log(LOG_NOTICE, "Attempted to delete non-existant schedule entry %d!\n", id); 00291 #ifdef DO_CRASH 00292 CRASH; 00293 #endif 00294 return -1; 00295 } else 00296 return 0; 00297 }
|
|
Dumps the scheduler contents.
Definition at line 299 of file sched.c. References ast_log(), sched::callback, sched::data, sched_context::eventcnt, sched::id, LOG_DEBUG, sched::next, sched_context::schedq, and sched::when. 00300 { 00301 /* 00302 * Dump the contents of the scheduler to 00303 * stderr 00304 */ 00305 struct sched *q; 00306 struct timeval tv; 00307 time_t s, ms; 00308 gettimeofday(&tv, NULL); 00309 #ifdef SCHED_MAX_CACHE 00310 ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", 00311 con-> schedcnt, con->eventcnt - 1, con->schedccnt); 00312 #else 00313 ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total)\n", 00314 con-> schedcnt, con->eventcnt - 1); 00315 #endif 00316 00317 ast_log(LOG_DEBUG, "=================================================\n"); 00318 ast_log(LOG_DEBUG, "|ID Callback Data Time (sec:ms) |\n"); 00319 ast_log(LOG_DEBUG, "+-----+-----------+-----------+-----------------+\n"); 00320 q = con->schedq; 00321 while(q) { 00322 s = q->when.tv_sec - tv.tv_sec; 00323 ms = q->when.tv_usec - tv.tv_usec; 00324 if (ms < 0) { 00325 ms += 1000000; 00326 s--; 00327 } 00328 ast_log(LOG_DEBUG, "|%.4d | %p | %p | %.6ld : %.6ld |\n", 00329 q->id, 00330 q->callback, 00331 q->data, 00332 (long)s, 00333 (long)ms); 00334 q=q->next; 00335 } 00336 ast_log(LOG_DEBUG, "=================================================\n"); 00337 00338 }
|
|
Runs the queue.
Definition at line 340 of file sched.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, sched::callback, sched::data, DEBUG, sched_context::lock, LOG_DEBUG, LOG_NOTICE, sched::next, sched::resched, sched_context::schedcnt, sched_context::schedq, SOONER, and sched::when. 00341 { 00342 /* 00343 * Launch all events which need to be run at this time. 00344 */ 00345 struct sched *current; 00346 struct timeval tv; 00347 int x=0; 00348 int res; 00349 DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n")); 00350 00351 ast_mutex_lock(&con->lock); 00352 for(;;) { 00353 if (!con->schedq) 00354 break; 00355 if (gettimeofday(&tv, NULL)) { 00356 /* This should never happen */ 00357 ast_log(LOG_NOTICE, "gettimeofday() failed!\n"); 00358 break; 00359 } 00360 /* We only care about millisecond accuracy anyway, so this will 00361 help us get more than one event at one time if they are very 00362 close together. */ 00363 tv.tv_usec += 1000; 00364 if (SOONER(con->schedq->when, tv)) { 00365 current = con->schedq; 00366 con->schedq = con->schedq->next; 00367 con->schedcnt--; 00368 00369 /* 00370 * At this point, the schedule queue is still intact. We 00371 * have removed the first event and the rest is still there, 00372 * so it's permissible for the callback to add new events, but 00373 * trying to delete itself won't work because it isn't in 00374 * the schedule queue. If that's what it wants to do, it 00375 * should return 0. 00376 */ 00377 00378 ast_mutex_unlock(&con->lock); 00379 res = current->callback(current->data); 00380 ast_mutex_lock(&con->lock); 00381 00382 if (res) { 00383 /* 00384 * If they return non-zero, we should schedule them to be 00385 * run again. 00386 */ 00387 if (sched_settime(¤t->when, current->resched)) { 00388 sched_release(con, current); 00389 } else 00390 schedule(con, current); 00391 } else { 00392 /* No longer needed, so release it */ 00393 sched_release(con, current); 00394 } 00395 x++; 00396 } else 00397 break; 00398 } 00399 ast_mutex_unlock(&con->lock); 00400 return x; 00401 }
|
|
Determines number of seconds until the next outstanding event to take place.
Definition at line 141 of file sched.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, DEBUG, sched_context::lock, LOG_DEBUG, sched_context::schedq, and sched::when. Referenced by ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full(). 00142 { 00143 /* 00144 * Return the number of milliseconds 00145 * until the next scheduled event 00146 */ 00147 struct timeval tv; 00148 int ms; 00149 DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n")); 00150 ast_mutex_lock(&con->lock); 00151 if (!con->schedq) { 00152 ms = -1; 00153 } else if (gettimeofday(&tv, NULL) < 0) { 00154 /* This should never happen */ 00155 ms = 0; 00156 } else { 00157 ms = (con->schedq->when.tv_sec - tv.tv_sec) * 1000; 00158 ms += (con->schedq->when.tv_usec - tv.tv_usec) / 1000; 00159 if (ms < 0) 00160 ms = 0; 00161 } 00162 ast_mutex_unlock(&con->lock); 00163 return ms; 00164 00165 }
|
|
New schedule context.
Definition at line 62 of file sched.c. References malloc. Referenced by ast_channel_alloc(). 00063 { 00064 struct sched_context *tmp; 00065 tmp = malloc(sizeof(struct sched_context)); 00066 if (tmp) { 00067 memset(tmp, 0, sizeof(struct sched_context)); 00068 ast_mutex_init(&tmp->lock); 00069 tmp->eventcnt = 1; 00070 tmp->schedcnt = 0; 00071 tmp->schedq = NULL; 00072 #ifdef SCHED_MAX_CACHE 00073 tmp->schedc = NULL; 00074 tmp->schedccnt = 0; 00075 #endif 00076 } 00077 return tmp; 00078 }
|
|
destroys a schedule context
Definition at line 80 of file sched.c. References ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, free, sched_context::lock, sched::next, s, and sched_context::schedq. Referenced by ast_hangup(). 00081 { 00082 struct sched *s, *sl; 00083 ast_mutex_lock(&con->lock); 00084 #ifdef SCHED_MAX_CACHE 00085 /* Eliminate the cache */ 00086 s = con->schedc; 00087 while(s) { 00088 sl = s; 00089 s = s->next; 00090 free(sl); 00091 } 00092 #endif 00093 /* And the queue */ 00094 s = con->schedq; 00095 while(s) { 00096 sl = s; 00097 s = s->next; 00098 free(sl); 00099 } 00100 /* And the context */ 00101 ast_mutex_unlock(&con->lock); 00102 ast_mutex_destroy(&con->lock); 00103 free(con); 00104 }
|