#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"
#include "asterisk/heap.h"
#include "asterisk/threadstorage.h"
Go to the source code of this file.
Data Structures | |
struct | ast_sched_thread |
struct | sched |
struct | sched_context |
Defines | |
#define | DEBUG(a) |
Functions | |
static void | __init_last_del_id (void) |
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_thread_add (struct ast_sched_thread *st, int when, ast_sched_cb cb, const void *data) |
Add a scheduler entry. | |
int | ast_sched_thread_add_variable (struct ast_sched_thread *st, int when, ast_sched_cb cb, const void *data, int variable) |
Add a variable reschedule time scheduler entry. | |
ast_sched_thread * | ast_sched_thread_create (void) |
Create a scheduler with a dedicated thread. | |
ast_sched_thread * | ast_sched_thread_destroy (struct ast_sched_thread *st) |
Destroy a scheduler and its thread. | |
sched_context * | ast_sched_thread_get_context (struct ast_sched_thread *st) |
Get the scheduler context for a given ast_sched_thread. | |
void | ast_sched_thread_poke (struct ast_sched_thread *st) |
Force re-processing of the scheduler context. | |
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 void * | sched_run (void *data) |
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 int | sched_time_cmp (void *a, void *b) |
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. | |
Variables | |
static struct ast_threadstorage | last_del_id = { .once = PTHREAD_ONCE_INIT , .key_init = __init_last_del_id , .custom_init = NULL , } |
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 442 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(), ast_sched_thread_add(), create_esc_entry(), do_register(), do_reload(), dundi_discover(), dundi_query(), dundi_send(), handle_command_response(), handle_request_invite(), handle_response_invite(), handle_response_subscribe(), mgcp_postrequest(), network_change_event_cb(), parse_register_contact(), populate_addr(), precache_trans(), qualify_peer(), receive_digit(), rtp_red_init(), sip_cc_agent_start_offer_timer(), sip_cc_monitor_request_cc(), sip_scheddestroy(), sip_send_all_mwi_subscriptions(), start_session_timer(), submit_scheduled_batch(), submit_unscheduled_batch(), transmit_register(), and update_provisional_keepalive().
00443 { 00444 return ast_sched_add_variable(con, when, callback, data, 0); 00445 }
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 402 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(), ast_sched_thread_add_variable(), dnsmgr_start_refresh(), and do_reload().
00403 { 00404 struct sched *tmp; 00405 int res = -1; 00406 00407 DEBUG(ast_debug(1, "ast_sched_add()\n")); 00408 00409 ast_mutex_lock(&con->lock); 00410 if ((tmp = sched_alloc(con))) { 00411 tmp->id = con->eventcnt++; 00412 tmp->callback = callback; 00413 tmp->data = data; 00414 tmp->resched = when; 00415 tmp->variable = variable; 00416 tmp->when = ast_tv(0, 0); 00417 if (sched_settime(&tmp->when, when)) { 00418 sched_release(con, tmp); 00419 } else { 00420 schedule(con, tmp); 00421 res = tmp->id; 00422 } 00423 } 00424 #ifdef DUMP_SCHEDULER 00425 /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */ 00426 if (option_debug) 00427 ast_sched_dump(con); 00428 #endif 00429 ast_mutex_unlock(&con->lock); 00430 00431 return res; 00432 }
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 464 of file sched.c.
References ast_assert, ast_debug, ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_heap_remove(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_dump(), ast_threadstorage_get(), DEBUG, sched::id, last_del_id, LOG_WARNING, option_debug, and sched_release().
Referenced by __sip_ack(), ast_rtp_prop_set(), ast_rtp_stop(), and destroy_event().
00468 { 00469 struct sched *s, tmp = { 00470 .id = id, 00471 }; 00472 int *last_id = ast_threadstorage_get(&last_del_id, sizeof(int *)); 00473 00474 DEBUG(ast_debug(1, "ast_sched_del(%d)\n", id)); 00475 00476 if (id < 0) { 00477 return 0; 00478 } 00479 00480 ast_mutex_lock(&con->lock); 00481 s = ast_hashtab_lookup(con->schedq_ht, &tmp); 00482 if (s) { 00483 if (!ast_heap_remove(con->sched_heap, s)) { 00484 ast_log(LOG_WARNING,"sched entry %d not in the sched heap?\n", s->id); 00485 } 00486 00487 if (!ast_hashtab_remove_this_object(con->schedq_ht, s)) { 00488 ast_log(LOG_WARNING,"Found sched entry %d, then couldn't remove it?\n", s->id); 00489 } 00490 00491 con->schedcnt--; 00492 00493 sched_release(con, s); 00494 } 00495 00496 #ifdef DUMP_SCHEDULER 00497 /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */ 00498 if (option_debug) 00499 ast_sched_dump(con); 00500 #endif 00501 ast_mutex_unlock(&con->lock); 00502 00503 if (!s && *last_id != id) { 00504 ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id); 00505 #ifndef AST_DEVMODE 00506 ast_assert(s != NULL); 00507 #else 00508 { 00509 char buf[100]; 00510 snprintf(buf, sizeof(buf), "s != NULL, id=%d", id); 00511 _ast_assert(0, buf, file, line, function); 00512 } 00513 #endif 00514 *last_id = id; 00515 return -1; 00516 } else if (!s) { 00517 return -1; 00518 } 00519 00520 return 0; 00521 }
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 561 of file sched.c.
References ast_debug, ast_heap_peek(), ast_heap_size(), 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::sched_heap, sched_context::schedccnt, sched_context::schedcnt, and sched::when.
Referenced by ast_sched_add_variable(), ast_sched_del(), handle_dump_sched(), sip_do_reload(), and unload_module().
00562 { 00563 struct sched *q; 00564 struct timeval when = ast_tvnow(); 00565 int x; 00566 size_t heap_size; 00567 #ifdef SCHED_MAX_CACHE 00568 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); 00569 #else 00570 ast_debug(1, "Asterisk Schedule Dump (%d in Q, %d Total, %d high-water)\n", con->schedcnt, con->eventcnt - 1, con->highwater); 00571 #endif 00572 00573 ast_debug(1, "=============================================================\n"); 00574 ast_debug(1, "|ID Callback Data Time (sec:ms) |\n"); 00575 ast_debug(1, "+-----+-----------------+-----------------+-----------------+\n"); 00576 ast_mutex_lock(&con->lock); 00577 heap_size = ast_heap_size(con->sched_heap); 00578 for (x = 1; x <= heap_size; x++) { 00579 struct timeval delta; 00580 q = ast_heap_peek(con->sched_heap, x); 00581 delta = ast_tvsub(q->when, when); 00582 ast_debug(1, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n", 00583 q->id, 00584 q->callback, 00585 q->data, 00586 (long)delta.tv_sec, 00587 (long int)delta.tv_usec); 00588 } 00589 ast_mutex_unlock(&con->lock); 00590 ast_debug(1, "=============================================================\n"); 00591 }
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 447 of file sched.c.
References ast_hashtab_lookup(), sched::data, sched::id, and sched_context::schedq_ht.
00448 { 00449 struct sched tmp,*res; 00450 tmp.id = id; 00451 res = ast_hashtab_lookup(con->schedq_ht, &tmp); 00452 if (res) 00453 return res->data; 00454 return NULL; 00455 }
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 434 of file sched.c.
References ast_sched_add(), and AST_SCHED_DEL.
00435 { 00436 if (old_id > -1) { 00437 AST_SCHED_DEL(con, old_id); 00438 } 00439 return ast_sched_add(con, when, callback, data); 00440 }
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 390 of file sched.c.
References ast_sched_add_variable(), and AST_SCHED_DEL.
00391 { 00392 /* 0 means the schedule item is new; do not delete */ 00393 if (old_id > 0) { 00394 AST_SCHED_DEL(con, old_id); 00395 } 00396 return ast_sched_add_variable(con, when, callback, data, variable); 00397 }
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 523 of file sched.c.
References ast_heap_peek(), ast_heap_size(), ast_mutex_lock, ast_str_set(), sched::callback, ast_cb_names::cblist, sched_context::highwater, sched_context::lock, ast_cb_names::numassocs, sched_context::sched_heap, and sched_context::schedcnt.
Referenced by sip_show_sched().
00524 { 00525 int i, x; 00526 struct sched *cur; 00527 int countlist[cbnames->numassocs + 1]; 00528 size_t heap_size; 00529 00530 memset(countlist, 0, sizeof(countlist)); 00531 ast_str_set(buf, 0, " Highwater = %d\n schedcnt = %d\n", con->highwater, con->schedcnt); 00532 00533 ast_mutex_lock(&con->lock); 00534 00535 heap_size = ast_heap_size(con->sched_heap); 00536 for (x = 1; x <= heap_size; x++) { 00537 cur = ast_heap_peek(con->sched_heap, x); 00538 /* match the callback to the cblist */ 00539 for (i = 0; i < cbnames->numassocs; i++) { 00540 if (cur->callback == cbnames->cblist[i]) { 00541 break; 00542 } 00543 } 00544 if (i < cbnames->numassocs) { 00545 countlist[i]++; 00546 } else { 00547 countlist[cbnames->numassocs]++; 00548 } 00549 } 00550 00551 ast_mutex_unlock(&con->lock); 00552 00553 for (i = 0; i < cbnames->numassocs; i++) { 00554 ast_str_append(buf, 0, " %s : %d\n", cbnames->list[i], countlist[i]); 00555 } 00556 00557 ast_str_append(buf, 0, " <unknown> : %d\n", countlist[cbnames->numassocs]); 00558 }
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 596 of file sched.c.
References ast_debug, ast_hashtab_remove_this_object(), ast_heap_peek(), ast_heap_pop(), 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_context::sched_heap, sched_release(), sched_settime(), sched_context::schedcnt, 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(), sched_run(), speech_background(), wait_for_winner(), and waitstream_core().
00597 { 00598 struct sched *current; 00599 struct timeval when; 00600 int numevents; 00601 int res; 00602 00603 DEBUG(ast_debug(1, "ast_sched_runq()\n")); 00604 00605 ast_mutex_lock(&con->lock); 00606 00607 when = ast_tvadd(ast_tvnow(), ast_tv(0, 1000)); 00608 for (numevents = 0; (current = ast_heap_peek(con->sched_heap, 1)); numevents++) { 00609 /* schedule all events which are going to expire within 1ms. 00610 * We only care about millisecond accuracy anyway, so this will 00611 * help us get more than one event at one time if they are very 00612 * close together. 00613 */ 00614 if (ast_tvcmp(current->when, when) != -1) { 00615 break; 00616 } 00617 00618 current = ast_heap_pop(con->sched_heap); 00619 00620 if (!ast_hashtab_remove_this_object(con->schedq_ht, current)) { 00621 ast_log(LOG_ERROR,"Sched entry %d was in the schedq list but not in the hashtab???\n", current->id); 00622 } 00623 00624 con->schedcnt--; 00625 00626 /* 00627 * At this point, the schedule queue is still intact. We 00628 * have removed the first event and the rest is still there, 00629 * so it's permissible for the callback to add new events, but 00630 * trying to delete itself won't work because it isn't in 00631 * the schedule queue. If that's what it wants to do, it 00632 * should return 0. 00633 */ 00634 00635 ast_mutex_unlock(&con->lock); 00636 res = current->callback(current->data); 00637 ast_mutex_lock(&con->lock); 00638 00639 if (res) { 00640 /* 00641 * If they return non-zero, we should schedule them to be 00642 * run again. 00643 */ 00644 if (sched_settime(¤t->when, current->variable? res : current->resched)) { 00645 sched_release(con, current); 00646 } else { 00647 schedule(con, current); 00648 } 00649 } else { 00650 /* No longer needed, so release it */ 00651 sched_release(con, current); 00652 } 00653 } 00654 00655 ast_mutex_unlock(&con->lock); 00656 00657 return numevents; 00658 }
int ast_sched_thread_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | cb, | |||
const void * | data | |||
) |
Add a scheduler entry.
st | the handle to the scheduler and thread | |
when | the number of ms in the future to run the task. A value <= 0 is treated as "run now". | |
cb | the function to call when the scheduled time arrives | |
data | the parameter to pass to the scheduler callback |
-1 | Failure | |
>=0 | Sched ID of added task |
Definition at line 206 of file sched.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), ast_sched_thread::cond, ast_sched_thread::context, and ast_sched_thread::lock.
Referenced by cc_generic_agent_start_offer_timer(), cc_generic_monitor_request_cc(), iax2_hangup(), iax2_key_rotate(), iax2_sched_add(), and iax2_sched_replace().
00208 { 00209 int res; 00210 00211 ast_mutex_lock(&st->lock); 00212 res = ast_sched_add(st->context, when, cb, data); 00213 if (res != -1) { 00214 ast_cond_signal(&st->cond); 00215 } 00216 ast_mutex_unlock(&st->lock); 00217 00218 return res; 00219 }
int ast_sched_thread_add_variable | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | cb, | |||
const void * | data, | |||
int | variable | |||
) |
Add a variable reschedule time scheduler entry.
st | the handle to the scheduler and thread | |
when | the number of ms in the future to run the task. A value <= 0 is treated as "run now". | |
cb | the function to call when the scheduled time arrives | |
data | the parameter to pass to the scheduler callback | |
variable | If this value is non-zero, then the scheduler will use the return value of the scheduler as the amount of time in the future to run the task again. Normally, a return value of 0 means do not re-schedule, and non-zero means re-schedule using the time provided when the scheduler entry was first created. |
-1 | Failure | |
>=0 | Sched ID of added task |
Definition at line 191 of file sched.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_sched_add_variable(), ast_sched_thread::cond, ast_sched_thread::context, and ast_sched_thread::lock.
Referenced by stun_start_monitor().
00193 { 00194 int res; 00195 00196 ast_mutex_lock(&st->lock); 00197 res = ast_sched_add_variable(st->context, when, cb, data, variable); 00198 if (res != -1) { 00199 ast_cond_signal(&st->cond); 00200 } 00201 ast_mutex_unlock(&st->lock); 00202 00203 return res; 00204 }
struct ast_sched_thread* ast_sched_thread_create | ( | void | ) |
Create a scheduler with a dedicated thread.
This function should be used to allocate a scheduler context and a dedicated thread for processing scheduler entries. The thread is started immediately.
NULL | error | |
non-NULL | a handle to the scheduler and its dedicated thread. |
Definition at line 163 of file sched.c.
References ast_calloc, ast_cond_init, ast_log(), ast_mutex_init, ast_pthread_create_background, AST_PTHREADT_NULL, ast_sched_thread_destroy(), LOG_ERROR, sched_context_create(), and sched_run().
Referenced by ast_cc_init(), load_module(), and stun_start_monitor().
00164 { 00165 struct ast_sched_thread *st; 00166 00167 if (!(st = ast_calloc(1, sizeof(*st)))) { 00168 return NULL; 00169 } 00170 00171 ast_mutex_init(&st->lock); 00172 ast_cond_init(&st->cond, NULL); 00173 00174 st->thread = AST_PTHREADT_NULL; 00175 00176 if (!(st->context = sched_context_create())) { 00177 ast_log(LOG_ERROR, "Failed to create scheduler\n"); 00178 ast_sched_thread_destroy(st); 00179 return NULL; 00180 } 00181 00182 if (ast_pthread_create_background(&st->thread, NULL, sched_run, st)) { 00183 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 00184 ast_sched_thread_destroy(st); 00185 return NULL; 00186 } 00187 00188 return st; 00189 }
struct ast_sched_thread* ast_sched_thread_destroy | ( | struct ast_sched_thread * | st | ) |
Destroy a scheduler and its thread.
This function is used to destroy a scheduler context and the dedicated thread that was created for handling scheduler entries. Any entries in the scheduler that have not yet been processed will be thrown away. Once this function is called, the handle must not be used again.
st | the handle to the scheduler and thread |
Definition at line 139 of file sched.c.
References ast_cond_destroy, ast_cond_signal, ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_sched_thread::cond, ast_sched_thread::context, ast_sched_thread::lock, sched_context_destroy(), ast_sched_thread::stop, and ast_sched_thread::thread.
Referenced by __unload_module(), ast_sched_thread_create(), load_module(), stun_start_monitor(), and stun_stop_monitor().
00140 { 00141 if (st->thread != AST_PTHREADT_NULL) { 00142 ast_mutex_lock(&st->lock); 00143 st->stop = 1; 00144 ast_cond_signal(&st->cond); 00145 ast_mutex_unlock(&st->lock); 00146 pthread_join(st->thread, NULL); 00147 st->thread = AST_PTHREADT_NULL; 00148 } 00149 00150 ast_mutex_destroy(&st->lock); 00151 ast_cond_destroy(&st->cond); 00152 00153 if (st->context) { 00154 sched_context_destroy(st->context); 00155 st->context = NULL; 00156 } 00157 00158 ast_free(st); 00159 00160 return NULL; 00161 }
struct sched_context* ast_sched_thread_get_context | ( | struct ast_sched_thread * | st | ) |
Get the scheduler context for a given ast_sched_thread.
This function should be used only when direct access to the scheduler context is required. Its use is discouraged unless necessary. The cases where this is currently required is when you want to take advantage of one of the AST_SCHED macros.
st | the handle to the scheduler and thread |
Definition at line 134 of file sched.c.
References ast_sched_thread::context.
Referenced by iax2_destroy_helper().
00135 { 00136 return st->context; 00137 }
void ast_sched_thread_poke | ( | struct ast_sched_thread * | st | ) |
Force re-processing of the scheduler context.
st | the handle to the scheduler and thread |
Definition at line 127 of file sched.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_sched_thread::cond, and ast_sched_thread::lock.
00128 { 00129 ast_mutex_lock(&st->lock); 00130 ast_cond_signal(&st->cond); 00131 ast_mutex_unlock(&st->lock); 00132 }
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 330 of file sched.c.
References ast_debug, ast_heap_peek(), ast_mutex_lock, ast_mutex_unlock, ast_tvdiff_ms(), ast_tvnow(), DEBUG, sched_context::lock, sched_context::sched_heap, 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(), sched_run(), speech_background(), wait_for_winner(), and waitstream_core().
00331 { 00332 int ms; 00333 struct sched *s; 00334 00335 DEBUG(ast_debug(1, "ast_sched_wait()\n")); 00336 00337 ast_mutex_lock(&con->lock); 00338 if ((s = ast_heap_peek(con->sched_heap, 1))) { 00339 ms = ast_tvdiff_ms(s->when, ast_tvnow()); 00340 if (ms < 0) { 00341 ms = 0; 00342 } 00343 } else { 00344 ms = -1; 00345 } 00346 ast_mutex_unlock(&con->lock); 00347 00348 return ms; 00349 }
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 660 of file sched.c.
References ast_debug, ast_hashtab_lookup(), ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), DEBUG, sched::id, sched_context::lock, sched_context::schedq_ht, and sched::when.
Referenced by _sip_show_peer(), handle_cli_status(), and parse_register_contact().
00661 { 00662 struct sched *s, tmp; 00663 long secs = -1; 00664 DEBUG(ast_debug(1, "ast_sched_when()\n")); 00665 00666 ast_mutex_lock(&con->lock); 00667 00668 /* these next 2 lines replace a lookup loop */ 00669 tmp.id = id; 00670 s = ast_hashtab_lookup(con->schedq_ht, &tmp); 00671 00672 if (s) { 00673 struct timeval now = ast_tvnow(); 00674 secs = s->when.tv_sec - now.tv_sec; 00675 } 00676 ast_mutex_unlock(&con->lock); 00677 00678 return secs; 00679 }
static struct sched* sched_alloc | ( | struct sched_context * | con | ) | [static] |
Definition at line 292 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().
00293 { 00294 struct sched *tmp; 00295 00296 /* 00297 * We keep a small cache of schedule entries 00298 * to minimize the number of necessary malloc()'s 00299 */ 00300 #ifdef SCHED_MAX_CACHE 00301 if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list))) 00302 con->schedccnt--; 00303 else 00304 #endif 00305 tmp = ast_calloc(1, sizeof(*tmp)); 00306 00307 return tmp; 00308 }
static int sched_cmp | ( | const void * | a, | |
const void * | b | |||
) | [static] |
struct sched_context* sched_context_create | ( | void | ) |
New schedule context.
Definition at line 242 of file sched.c.
References ast_calloc, ast_hashtab_create(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_heap_create(), ast_mutex_init, sched_cmp(), sched_context_destroy(), sched_hash(), and sched_time_cmp().
Referenced by __ast_channel_alloc_ap(), ast_cdr_engine_init(), ast_sched_thread_create(), dnsmgr_init(), load_module(), and misdn_tasks_init().
00243 { 00244 struct sched_context *tmp; 00245 00246 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 00247 return NULL; 00248 00249 ast_mutex_init(&tmp->lock); 00250 tmp->eventcnt = 1; 00251 00252 tmp->schedq_ht = ast_hashtab_create(23, sched_cmp, ast_hashtab_resize_java, ast_hashtab_newsize_java, sched_hash, 1); 00253 00254 if (!(tmp->sched_heap = ast_heap_create(8, sched_time_cmp, 00255 offsetof(struct sched, __heap_index)))) { 00256 sched_context_destroy(tmp); 00257 return NULL; 00258 } 00259 00260 return tmp; 00261 }
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 263 of file sched.c.
References ast_free, ast_hashtab_destroy(), ast_heap_destroy(), ast_heap_pop(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, sched::list, sched_context::lock, sched_context::sched_heap, sched_context::schedc, and sched_context::schedq_ht.
Referenced by ast_channel_destructor(), ast_hangup(), ast_sched_thread_destroy(), load_module(), misdn_tasks_destroy(), sched_context_create(), and unload_module().
00264 { 00265 struct sched *s; 00266 00267 ast_mutex_lock(&con->lock); 00268 00269 #ifdef SCHED_MAX_CACHE 00270 /* Eliminate the cache */ 00271 while ((s = AST_LIST_REMOVE_HEAD(&con->schedc, list))) 00272 ast_free(s); 00273 #endif 00274 00275 if (con->sched_heap) { 00276 while ((s = ast_heap_pop(con->sched_heap))) { 00277 ast_free(s); 00278 } 00279 ast_heap_destroy(con->sched_heap); 00280 con->sched_heap = NULL; 00281 } 00282 00283 ast_hashtab_destroy(con->schedq_ht, NULL); 00284 con->schedq_ht = NULL; 00285 00286 /* And the context */ 00287 ast_mutex_unlock(&con->lock); 00288 ast_mutex_destroy(&con->lock); 00289 ast_free(con); 00290 }
static unsigned int sched_hash | ( | const void * | obj | ) | [static] |
static void sched_release | ( | struct sched_context * | con, | |
struct sched * | tmp | |||
) | [static] |
Definition at line 310 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().
00311 { 00312 /* 00313 * Add to the cache, or just free() if we 00314 * already have too many cache entries 00315 */ 00316 00317 #ifdef SCHED_MAX_CACHE 00318 if (con->schedccnt < SCHED_MAX_CACHE) { 00319 AST_LIST_INSERT_HEAD(&con->schedc, tmp, list); 00320 con->schedccnt++; 00321 } else 00322 #endif 00323 ast_free(tmp); 00324 }
static void* sched_run | ( | void * | data | ) | [static] |
Definition at line 86 of file sched.c.
References ast_cond_timedwait, ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), ast_sched_thread::cond, ast_sched_thread::context, ast_sched_thread::lock, and ast_sched_thread::stop.
Referenced by ast_sched_thread_create().
00087 { 00088 struct ast_sched_thread *st = data; 00089 00090 while (!st->stop) { 00091 int ms; 00092 struct timespec ts = { 00093 .tv_sec = 0, 00094 }; 00095 00096 ast_mutex_lock(&st->lock); 00097 00098 if (st->stop) { 00099 ast_mutex_unlock(&st->lock); 00100 return NULL; 00101 } 00102 00103 ms = ast_sched_wait(st->context); 00104 00105 if (ms == -1) { 00106 ast_cond_wait(&st->cond, &st->lock); 00107 } else { 00108 struct timeval tv; 00109 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 00110 ts.tv_sec = tv.tv_sec; 00111 ts.tv_nsec = tv.tv_usec * 1000; 00112 ast_cond_timedwait(&st->cond, &st->lock, &ts); 00113 } 00114 00115 ast_mutex_unlock(&st->lock); 00116 00117 if (st->stop) { 00118 return NULL; 00119 } 00120 00121 ast_sched_runq(st->context); 00122 } 00123 00124 return NULL; 00125 }
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 376 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().
00377 { 00378 struct timeval now = ast_tvnow(); 00379 00380 /*ast_debug(1, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/ 00381 if (ast_tvzero(*t)) /* not supplied, default to now */ 00382 *t = now; 00383 *t = ast_tvadd(*t, ast_samp2tv(when, 1000)); 00384 if (ast_tvcmp(*t, now) < 0) { 00385 *t = now; 00386 } 00387 return 0; 00388 }
static int sched_time_cmp | ( | void * | a, | |
void * | b | |||
) | [static] |
Definition at line 237 of file sched.c.
References ast_tvcmp().
Referenced by sched_context_create().
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 357 of file sched.c.
References ast_hashtab_insert_safe(), ast_heap_push(), ast_log(), sched_context::highwater, sched::id, LOG_WARNING, sched_context::sched_heap, sched_context::schedcnt, and sched_context::schedq_ht.
Referenced by ast_sched_add_variable(), and ast_sched_runq().
00358 { 00359 ast_heap_push(con->sched_heap, s); 00360 00361 if (!ast_hashtab_insert_safe(con->schedq_ht, s)) { 00362 ast_log(LOG_WARNING,"Schedule Queue entry %d is already in table!\n", s->id); 00363 } 00364 00365 con->schedcnt++; 00366 00367 if (con->schedcnt > con->highwater) { 00368 con->highwater = con->schedcnt; 00369 } 00370 }
struct ast_threadstorage last_del_id = { .once = PTHREAD_ONCE_INIT , .key_init = __init_last_del_id , .custom_init = NULL , } [static] |