#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 }
|
1.4.2