#include "asterisk.h"
#include <sys/time.h>
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dlinkedlists.h"
#include "asterisk/hashtab.h"
Go to the source code of this file.
Data Structures | |
struct | sched |
struct | sched_context |
Defines | |
#define | DEBUG(a) |
Functions | |
int | ast_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled. | |
int | ast_sched_add_variable (struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) |
Schedule callback(data) to happen when ms into the future. | |
int | ast_sched_del (struct sched_context *con, int id) |
Deletes a scheduled event Remove this event from being run. A procedure should not remove its own event, but return 0 instead. In most cases, you should not call this routine directly, but use the AST_SCHED_DEL() macro instead (especially if you don't intend to do something different when it returns failure). | |
void | ast_sched_dump (struct sched_context *con) |
Dumps the scheduler contents Debugging: Dump the contents of the scheduler to stderr. | |
const void * | ast_sched_find_data (struct sched_context *con, int id) |
Find a sched structure and return the data field associated with it. | |
int | ast_sched_replace (int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
replace a scheduler entry | |
int | ast_sched_replace_variable (int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) |
replace a scheduler entry | |
void | ast_sched_report (struct sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames) |
Show statics on what it is in the schedule queue. | |
int | ast_sched_runq (struct sched_context *con) |
Runs the queue. | |
int | ast_sched_wait (struct sched_context *con) |
Determines number of seconds until the next outstanding event to take place Determine the number of seconds until the next outstanding event should take place, and return the number of milliseconds until it needs to be run. This value is perfect for passing to the poll call. | |
long | ast_sched_when (struct sched_context *con, int id) |
Returns the number of seconds before an event takes place. | |
static struct sched * | sched_alloc (struct sched_context *con) |
static int | sched_cmp (const void *a, const void *b) |
sched_context * | sched_context_create (void) |
New schedule context. | |
void | sched_context_destroy (struct sched_context *con) |
destroys a schedule context Destroys (free's) the given sched_context structure | |
static unsigned int | sched_hash (const void *obj) |
static void | sched_release (struct sched_context *con, struct sched *tmp) |
static int | sched_settime (struct timeval *t, int when) |
given the last event *tv and the offset in milliseconds 'when', computes the next value, | |
static void | schedule (struct sched_context *con, struct sched *s) |
Take a sched structure and put it in the queue, such that the soonest event is first in the list. |
Definition in file sched.c.
int ast_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) |
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
con | Scheduler context to add | |
when | how many milliseconds to wait for event to occur | |
callback | function to call when the amount of time expires | |
data | data to pass to the callback |
Definition at line 314 of file sched.c.
References ast_sched_add_variable().
Referenced by __oh323_update_info(), ast_readaudio_callback(), ast_readvideo_callback(), ast_rtp_raw_write(), ast_rtp_read(), ast_sched_replace(), do_register(), do_reload(), dundi_discover(), dundi_query(), dundi_send(), handle_command_response(), handle_request_invite(), handle_response_invite(), iax2_hangup(), iax2_key_rotate(), iax2_sched_add(), mgcp_postrequest(), parse_register_contact(), populate_addr(), precache_trans(), qualify_peer(), queue_request(), receive_digit(), rtp_red_init(), sip_scheddestroy(), start_session_timer(), submit_scheduled_batch(), submit_unscheduled_batch(), transmit_register(), and update_provisional_keepalive().
00315 { 00316 return ast_sched_add_variable(con, when, callback, data, 0); 00317 }
int ast_sched_add_variable | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) |
Schedule callback(data) to happen when ms into the future.
Adds a scheduled event with rescheduling support
con | Scheduler context to add | |
when | how many milliseconds to wait for event to occur | |
callback | function to call when the amount of time expires | |
data | data to pass to the callback | |
variable | If true, the result value of callback function will be used for rescheduling Schedule an event to take place at some point in the future. Callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled |
Definition at line 274 of file sched.c.
References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_dump(), ast_tv(), sched::callback, sched::data, DEBUG, sched_context::eventcnt, sched::id, sched_context::lock, option_debug, sched::resched, sched_alloc(), sched_release(), sched_settime(), schedule(), sched::variable, and sched::when.
Referenced by _misdn_tasks_add_variable(), ast_sched_add(), ast_sched_replace_variable(), dnsmgr_start_refresh(), and do_reload().
00275 { 00276 struct sched *tmp; 00277 int res = -1; 00278 00279 DEBUG(ast_debug(1, "ast_sched_add()\n")); 00280 00281 ast_mutex_lock(&con->lock); 00282 if ((tmp = sched_alloc(con))) { 00283 tmp->id = con->eventcnt++; 00284 tmp->callback = callback; 00285 tmp->data = data; 00286 tmp->resched = when; 00287 tmp->variable = variable; 00288 tmp->when = ast_tv(0, 0); 00289 if (sched_settime(&tmp->when, when)) { 00290 sched_release(con, tmp); 00291 } else { 00292 schedule(con, tmp); 00293 res = tmp->id; 00294 } 00295 } 00296 #ifdef DUMP_SCHEDULER 00297 /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */ 00298 if (option_debug) 00299 ast_sched_dump(con); 00300 #endif 00301 ast_mutex_unlock(&con->lock); 00302 00303 return res; 00304 }
int ast_sched_del | ( | struct sched_context * | con, | |
int | id | |||
) |
Deletes a scheduled event Remove this event from being run. A procedure should not remove its own event, but return 0 instead. In most cases, you should not call this routine directly, but use the AST_SCHED_DEL() macro instead (especially if you don't intend to do something different when it returns failure).
con | scheduling context to delete item from | |
id | ID of the scheduled item to delete |
Definition at line 336 of file sched.c.
References ast_assert, ast_debug, AST_DLLIST_REMOVE, ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_dump(), DEBUG, sched::id, sched::list, LOG_WARNING, option_debug, s, and sched_release().
Referenced by __sip_ack(), iax2_poke_peer(), reg_source_db(), sip_cancel_destroy(), socket_process(), unlink_peer(), and update_registry().
00340 { 00341 struct sched *s, tmp; 00342 00343 DEBUG(ast_debug(1, "ast_sched_del(%d)\n", id)); 00344 00345 ast_mutex_lock(&con->lock); 00346 00347 /* OK, this is the heart of the sched performance upgrade. 00348 If we have 4700 peers, we can have 4700+ entries in the 00349 schedq list. searching this would take time. So, I add a 00350 hashtab to the context to keep track of each entry, by id. 00351 I also leave the linked list alone, almost, -- I implement 00352 a doubly-linked list instead, because it would do little good 00353 to look up the id in a hashtab, and then have to run thru 00354 a couple thousand entries to remove it from the schedq list! */ 00355 tmp.id = id; 00356 s = ast_hashtab_lookup(con->schedq_ht, &tmp); 00357 if (s) { 00358 struct sched *x = AST_DLLIST_REMOVE(&con->schedq, s, list); 00359 00360 if (!x) 00361 ast_log(LOG_WARNING,"sched entry %d not in the schedq list?\n", s->id); 00362 00363 if (!ast_hashtab_remove_this_object(con->schedq_ht, s)) 00364 ast_log(LOG_WARNING,"Found sched entry %d, then couldn't remove it?\n", s->id); 00365 con->schedcnt--; 00366 sched_release(con, s); 00367 } 00368 00369 #ifdef DUMP_SCHEDULER 00370 /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */ 00371 if (option_debug) 00372 ast_sched_dump(con); 00373 #endif 00374 ast_mutex_unlock(&con->lock); 00375 00376 if (!s) { 00377 ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id); 00378 #ifndef AST_DEVMODE 00379 ast_assert(s != NULL); 00380 #else 00381 _ast_assert(0, "s != NULL", file, line, function); 00382 #endif 00383 return -1; 00384 } 00385 00386 return 0; 00387 }
void ast_sched_dump | ( | struct sched_context * | con | ) |
Dumps the scheduler contents Debugging: Dump the contents of the scheduler to stderr.
con | Context to dump |
Definition at line 422 of file sched.c.
References ast_debug, AST_DLLIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_tvnow(), ast_tvsub(), sched::callback, sched::data, sched_context::eventcnt, sched_context::highwater, sched::id, sched_context::lock, sched_context::schedccnt, sched_context::schedcnt, sched_context::schedq, and sched::when.
Referenced by ast_sched_add_variable(), ast_sched_del(), sip_do_reload(), and unload_module().
00423 { 00424 struct sched *q; 00425 struct timeval when = ast_tvnow(); 00426 #ifdef SCHED_MAX_CACHE 00427 ast_debug(1, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache, %d high-water)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt, con->highwater); 00428 #else 00429 ast_debug(1, "Asterisk Schedule Dump (%d in Q, %d Total, %d high-water)\n", con->schedcnt, con->eventcnt - 1, con->highwater); 00430 #endif 00431 00432 ast_debug(1, "=============================================================\n"); 00433 ast_debug(1, "|ID Callback Data Time (sec:ms) |\n"); 00434 ast_debug(1, "+-----+-----------------+-----------------+-----------------+\n"); 00435 ast_mutex_lock(&con->lock); 00436 AST_DLLIST_TRAVERSE(&con->schedq, q, list) { 00437 struct timeval delta = ast_tvsub(q->when, when); 00438 00439 ast_debug(1, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n", 00440 q->id, 00441 q->callback, 00442 q->data, 00443 (long)delta.tv_sec, 00444 (long int)delta.tv_usec); 00445 } 00446 ast_mutex_unlock(&con->lock); 00447 ast_debug(1, "=============================================================\n"); 00448 }
const void* ast_sched_find_data | ( | struct sched_context * | con, | |
int | id | |||
) |
Find a sched structure and return the data field associated with it.
con | scheduling context in which to search fro the matching id | |
id | ID of the scheduled item to find |
Definition at line 319 of file sched.c.
References ast_hashtab_lookup(), sched::data, sched::id, and sched_context::schedq_ht.
00320 { 00321 struct sched tmp,*res; 00322 tmp.id = id; 00323 res = ast_hashtab_lookup(con->schedq_ht, &tmp); 00324 if (res) 00325 return res->data; 00326 return NULL; 00327 }
int ast_sched_replace | ( | int | old_id, | |
struct sched_context * | con, | |||
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) |
replace a scheduler entry
-1 | failure | |
otherwise,returns | scheduled item ID |
Definition at line 306 of file sched.c.
References ast_sched_add(), and AST_SCHED_DEL.
00307 { 00308 if (old_id > -1) { 00309 AST_SCHED_DEL(con, old_id); 00310 } 00311 return ast_sched_add(con, when, callback, data); 00312 }
int ast_sched_replace_variable | ( | int | old_id, | |
struct sched_context * | con, | |||
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) |
replace a scheduler entry
-1 | failure | |
otherwise,returns | scheduled item ID |
Definition at line 262 of file sched.c.
References ast_sched_add_variable(), and AST_SCHED_DEL.
00263 { 00264 /* 0 means the schedule item is new; do not delete */ 00265 if (old_id > 0) { 00266 AST_SCHED_DEL(con, old_id); 00267 } 00268 return ast_sched_add_variable(con, when, callback, data, variable); 00269 }
void ast_sched_report | ( | struct sched_context * | con, | |
struct ast_str ** | buf, | |||
struct ast_cb_names * | cbnames | |||
) |
Show statics on what it is in the schedule queue.
con | Schedule context to check | |
buf | dynamic string to store report | |
cbnames | to check against |
Definition at line 389 of file sched.c.
References AST_DLLIST_TRAVERSE, ast_mutex_lock(), ast_str_set(), buf, sched::callback, ast_cb_names::cblist, sched_context::highwater, sched::list, sched_context::lock, ast_cb_names::numassocs, sched_context::schedcnt, and sched_context::schedq.
Referenced by sip_show_sched().
00390 { 00391 int i; 00392 struct sched *cur; 00393 int countlist[cbnames->numassocs + 1]; 00394 00395 memset(countlist, 0, sizeof(countlist)); 00396 ast_str_set(buf, 0, " Highwater = %d\n schedcnt = %d\n", con->highwater, con->schedcnt); 00397 00398 ast_mutex_lock(&con->lock); 00399 AST_DLLIST_TRAVERSE(&con->schedq, cur, list) { 00400 /* match the callback to the cblist */ 00401 for (i = 0; i < cbnames->numassocs; i++) { 00402 if (cur->callback == cbnames->cblist[i]) { 00403 break; 00404 } 00405 } 00406 if (i < cbnames->numassocs) { 00407 countlist[i]++; 00408 } else { 00409 countlist[cbnames->numassocs]++; 00410 } 00411 } 00412 ast_mutex_unlock(&con->lock); 00413 00414 for (i = 0; i < cbnames->numassocs; i++) { 00415 ast_str_append(buf, 0, " %s : %d\n", cbnames->list[i], countlist[i]); 00416 } 00417 00418 ast_str_append(buf, 0, " <unknown> : %d\n", countlist[cbnames->numassocs]); 00419 }
int ast_sched_runq | ( | struct sched_context * | con | ) |
Runs the queue.
con | Scheduling context to run Run the queue, executing all callbacks which need to be performed at this time. | |
con | context to act upon |
Definition at line 453 of file sched.c.
References ast_debug, AST_DLLIST_EMPTY, AST_DLLIST_FIRST, AST_DLLIST_REMOVE_HEAD, ast_hashtab_remove_this_object(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_tv(), ast_tvadd(), ast_tvcmp(), ast_tvnow(), sched::callback, sched::data, DEBUG, sched::id, sched_context::lock, LOG_ERROR, sched::resched, sched_release(), sched_settime(), sched_context::schedcnt, sched_context::schedq, sched_context::schedq_ht, schedule(), sched::variable, and sched::when.
Referenced by background_detect_exec(), dial_exec_full(), do_cdr(), do_monitor(), do_refresh(), handle_speechrecognize(), misdn_tasks_thread_func(), network_thread(), reload_config(), sched_thread(), speech_background(), wait_for_winner(), and waitstream_core().
00454 { 00455 struct sched *current; 00456 struct timeval when; 00457 int numevents; 00458 int res; 00459 00460 DEBUG(ast_debug(1, "ast_sched_runq()\n")); 00461 00462 ast_mutex_lock(&con->lock); 00463 00464 for (numevents = 0; !AST_DLLIST_EMPTY(&con->schedq); numevents++) { 00465 /* schedule all events which are going to expire within 1ms. 00466 * We only care about millisecond accuracy anyway, so this will 00467 * help us get more than one event at one time if they are very 00468 * close together. 00469 */ 00470 when = ast_tvadd(ast_tvnow(), ast_tv(0, 1000)); 00471 if (ast_tvcmp(AST_DLLIST_FIRST(&con->schedq)->when, when) != -1) 00472 break; 00473 00474 current = AST_DLLIST_REMOVE_HEAD(&con->schedq, list); 00475 if (!ast_hashtab_remove_this_object(con->schedq_ht, current)) 00476 ast_log(LOG_ERROR,"Sched entry %d was in the schedq list but not in the hashtab???\n", current->id); 00477 00478 con->schedcnt--; 00479 00480 /* 00481 * At this point, the schedule queue is still intact. We 00482 * have removed the first event and the rest is still there, 00483 * so it's permissible for the callback to add new events, but 00484 * trying to delete itself won't work because it isn't in 00485 * the schedule queue. If that's what it wants to do, it 00486 * should return 0. 00487 */ 00488 00489 ast_mutex_unlock(&con->lock); 00490 res = current->callback(current->data); 00491 ast_mutex_lock(&con->lock); 00492 00493 if (res) { 00494 /* 00495 * If they return non-zero, we should schedule them to be 00496 * run again. 00497 */ 00498 if (sched_settime(¤t->when, current->variable? res : current->resched)) { 00499 sched_release(con, current); 00500 } else 00501 schedule(con, current); 00502 } else { 00503 /* No longer needed, so release it */ 00504 sched_release(con, current); 00505 } 00506 } 00507 00508 ast_mutex_unlock(&con->lock); 00509 00510 return numevents; 00511 }
int ast_sched_wait | ( | struct sched_context * | con | ) |
Determines number of seconds until the next outstanding event to take place Determine the number of seconds until the next outstanding event should take place, and return the number of milliseconds until it needs to be run. This value is perfect for passing to the poll call.
con | context to act upon |
Definition at line 168 of file sched.c.
References ast_debug, AST_DLLIST_EMPTY, AST_DLLIST_FIRST, ast_mutex_lock(), ast_mutex_unlock(), ast_tvdiff_ms(), ast_tvnow(), DEBUG, sched_context::lock, and sched_context::schedq.
Referenced by background_detect_exec(), dial_exec_full(), do_cdr(), do_monitor(), do_refresh(), handle_speechrecognize(), misdn_tasks_thread_func(), network_thread(), sched_thread(), speech_background(), wait_for_winner(), and waitstream_core().
00169 { 00170 int ms; 00171 00172 DEBUG(ast_debug(1, "ast_sched_wait()\n")); 00173 00174 ast_mutex_lock(&con->lock); 00175 if (AST_DLLIST_EMPTY(&con->schedq)) { 00176 ms = -1; 00177 } else { 00178 ms = ast_tvdiff_ms(AST_DLLIST_FIRST(&con->schedq)->when, ast_tvnow()); 00179 if (ms < 0) 00180 ms = 0; 00181 } 00182 ast_mutex_unlock(&con->lock); 00183 00184 return ms; 00185 }
long ast_sched_when | ( | struct sched_context * | con, | |
int | id | |||
) |
Returns the number of seconds before an event takes place.
con | Context to use | |
id | Id to dump |
Definition at line 513 of file sched.c.
References ast_debug, ast_hashtab_lookup(), ast_mutex_lock(), ast_mutex_unlock(), ast_tvnow(), DEBUG, sched::id, sched_context::lock, s, and sched_context::schedq_ht.
Referenced by _sip_show_peer(), handle_cli_status(), and parse_register_contact().
00514 { 00515 struct sched *s, tmp; 00516 long secs = -1; 00517 DEBUG(ast_debug(1, "ast_sched_when()\n")); 00518 00519 ast_mutex_lock(&con->lock); 00520 00521 /* these next 2 lines replace a lookup loop */ 00522 tmp.id = id; 00523 s = ast_hashtab_lookup(con->schedq_ht, &tmp); 00524 00525 if (s) { 00526 struct timeval now = ast_tvnow(); 00527 secs = s->when.tv_sec - now.tv_sec; 00528 } 00529 ast_mutex_unlock(&con->lock); 00530 00531 return secs; 00532 }
static struct sched* sched_alloc | ( | struct sched_context * | con | ) | [static] |
Definition at line 130 of file sched.c.
References ast_calloc, AST_LIST_REMOVE_HEAD, sched::list, sched_context::schedc, and sched_context::schedccnt.
Referenced by ast_sched_add_variable().
00131 { 00132 struct sched *tmp; 00133 00134 /* 00135 * We keep a small cache of schedule entries 00136 * to minimize the number of necessary malloc()'s 00137 */ 00138 #ifdef SCHED_MAX_CACHE 00139 if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list))) 00140 con->schedccnt--; 00141 else 00142 #endif 00143 tmp = ast_calloc(1, sizeof(*tmp)); 00144 00145 return tmp; 00146 }
static int sched_cmp | ( | const void * | a, | |
const void * | b | |||
) | [static] |
struct sched_context* sched_context_create | ( | void | ) |
New schedule context.
Definition at line 90 of file sched.c.
References ast_calloc, ast_hashtab_create(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_mutex_init(), sched_cmp(), and sched_hash().
Referenced by __ast_channel_alloc_ap(), ast_cdr_engine_init(), dnsmgr_init(), load_module(), and misdn_tasks_init().
00091 { 00092 struct sched_context *tmp; 00093 00094 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 00095 return NULL; 00096 00097 ast_mutex_init(&tmp->lock); 00098 tmp->eventcnt = 1; 00099 00100 tmp->schedq_ht = ast_hashtab_create(23, sched_cmp, ast_hashtab_resize_java, ast_hashtab_newsize_java, sched_hash, 1); 00101 00102 return tmp; 00103 }
void sched_context_destroy | ( | struct sched_context * | c | ) |
destroys a schedule context Destroys (free's) the given sched_context structure
c | Context to free |
Definition at line 105 of file sched.c.
References AST_DLLIST_REMOVE_HEAD, ast_free, ast_hashtab_destroy(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), sched::list, sched_context::lock, s, sched_context::schedc, sched_context::schedq, and sched_context::schedq_ht.
Referenced by __ast_channel_alloc_ap(), __unload_module(), ast_channel_free(), ast_hangup(), load_module(), misdn_tasks_destroy(), and unload_module().
00106 { 00107 struct sched *s; 00108 00109 ast_mutex_lock(&con->lock); 00110 00111 #ifdef SCHED_MAX_CACHE 00112 /* Eliminate the cache */ 00113 while ((s = AST_LIST_REMOVE_HEAD(&con->schedc, list))) 00114 ast_free(s); 00115 #endif 00116 00117 /* And the queue */ 00118 while ((s = AST_DLLIST_REMOVE_HEAD(&con->schedq, list))) 00119 ast_free(s); 00120 00121 ast_hashtab_destroy(con->schedq_ht, NULL); 00122 con->schedq_ht = NULL; 00123 00124 /* And the context */ 00125 ast_mutex_unlock(&con->lock); 00126 ast_mutex_destroy(&con->lock); 00127 ast_free(con); 00128 }
static unsigned int sched_hash | ( | const void * | obj | ) | [static] |
static void sched_release | ( | struct sched_context * | con, | |
struct sched * | tmp | |||
) | [static] |
Definition at line 148 of file sched.c.
References ast_free, AST_LIST_INSERT_HEAD, sched::list, SCHED_MAX_CACHE, sched_context::schedc, and sched_context::schedccnt.
Referenced by ast_sched_add_variable(), ast_sched_del(), and ast_sched_runq().
00149 { 00150 /* 00151 * Add to the cache, or just free() if we 00152 * already have too many cache entries 00153 */ 00154 00155 #ifdef SCHED_MAX_CACHE 00156 if (con->schedccnt < SCHED_MAX_CACHE) { 00157 AST_LIST_INSERT_HEAD(&con->schedc, tmp, list); 00158 con->schedccnt++; 00159 } else 00160 #endif 00161 ast_free(tmp); 00162 }
static int sched_settime | ( | struct timeval * | t, | |
int | when | |||
) | [static] |
given the last event *tv and the offset in milliseconds 'when', computes the next value,
Definition at line 248 of file sched.c.
References ast_samp2tv(), ast_tvadd(), ast_tvcmp(), ast_tvnow(), and ast_tvzero().
Referenced by ast_sched_add_variable(), and ast_sched_runq().
00249 { 00250 struct timeval now = ast_tvnow(); 00251 00252 /*ast_debug(1, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/ 00253 if (ast_tvzero(*t)) /* not supplied, default to now */ 00254 *t = now; 00255 *t = ast_tvadd(*t, ast_samp2tv(when, 1000)); 00256 if (ast_tvcmp(*t, now) < 0) { 00257 *t = now; 00258 } 00259 return 0; 00260 }
static void schedule | ( | struct sched_context * | con, | |
struct sched * | s | |||
) | [static] |
Take a sched structure and put it in the queue, such that the soonest event is first in the list.
Definition at line 193 of file sched.c.
References AST_DLLIST_FIRST, AST_DLLIST_INSERT_AFTER, AST_DLLIST_INSERT_BEFORE, AST_DLLIST_INSERT_HEAD, AST_DLLIST_INSERT_TAIL, AST_DLLIST_LAST, AST_DLLIST_TRAVERSE, AST_DLLIST_TRAVERSE_BACKWARDS, ast_hashtab_insert_safe(), ast_log(), ast_tvcmp(), ast_tvdiff_us(), first, sched_context::highwater, last, sched::list, LOG_WARNING, s, sched_context::schedcnt, sched_context::schedq, sched_context::schedq_ht, and sched::when.
Referenced by ast_sched_add_variable(), and ast_sched_runq().
00194 { 00195 struct sched *cur = NULL; 00196 int ret; 00197 int df = 0; 00198 int de = 0; 00199 struct sched *first = AST_DLLIST_FIRST(&con->schedq); 00200 struct sched *last = AST_DLLIST_LAST(&con->schedq); 00201 00202 if (first) 00203 df = ast_tvdiff_us(s->when, first->when); 00204 if (last) 00205 de = ast_tvdiff_us(s->when, last->when); 00206 00207 if (df < 0) 00208 df = -df; 00209 if (de < 0) 00210 de = -de; 00211 00212 if (df < de) { 00213 AST_DLLIST_TRAVERSE(&con->schedq, cur, list) { 00214 if (ast_tvcmp(s->when, cur->when) == -1) { 00215 AST_DLLIST_INSERT_BEFORE(&con->schedq, cur, s, list); 00216 break; 00217 } 00218 } 00219 if (!cur) { 00220 AST_DLLIST_INSERT_TAIL(&con->schedq, s, list); 00221 } 00222 } else { 00223 AST_DLLIST_TRAVERSE_BACKWARDS(&con->schedq, cur, list) { 00224 if (ast_tvcmp(s->when, cur->when) == 1) { 00225 AST_DLLIST_INSERT_AFTER(&con->schedq, cur, s, list); 00226 break; 00227 } 00228 } 00229 if (!cur) { 00230 AST_DLLIST_INSERT_HEAD(&con->schedq, s, list); 00231 } 00232 } 00233 00234 ret = ast_hashtab_insert_safe(con->schedq_ht, s); 00235 if (!ret) 00236 ast_log(LOG_WARNING,"Schedule Queue entry %d is already in table!\n",s->id); 00237 00238 con->schedcnt++; 00239 00240 if (con->schedcnt > con->highwater) 00241 con->highwater = con->schedcnt; 00242 }