Timing source management. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/timing.h"#include "asterisk/lock.h"#include "asterisk/cli.h"#include "asterisk/utils.h"#include "asterisk/time.h"#include "asterisk/heap.h"#include "asterisk/module.h"#include "asterisk/poll-compat.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_timer |
| struct | timing_holder |
Functions | |
| void * | _ast_register_timing_interface (struct ast_timing_interface *funcs, struct ast_module *mod) |
| int | ast_timer_ack (const struct ast_timer *handle, unsigned int quantity) |
| Acknowledge a timer event. | |
| void | ast_timer_close (struct ast_timer *handle) |
| Close an opened timing handle. | |
| int | ast_timer_disable_continuous (const struct ast_timer *handle) |
| Disable continuous mode. | |
| int | ast_timer_enable_continuous (const struct ast_timer *handle) |
| Enable continuous mode. | |
| int | ast_timer_fd (const struct ast_timer *handle) |
| Get a poll()-able file descriptor for a timer. | |
| enum ast_timer_event | ast_timer_get_event (const struct ast_timer *handle) |
| Retrieve timing event. | |
| unsigned int | ast_timer_get_max_rate (const struct ast_timer *handle) |
| Get maximum rate supported for a timer. | |
| const char * | ast_timer_get_name (const struct ast_timer *handle) |
| Get name of timer in use. | |
| struct ast_timer * | ast_timer_open (void) |
| Open a timer. | |
| int | ast_timer_set_rate (const struct ast_timer *handle, unsigned int rate) |
| Set the timing tick rate. | |
| int | ast_timing_init (void) |
| int | ast_unregister_timing_interface (void *handle) |
| Unregister a previously registered timing interface. | |
| static int | timing_holder_cmp (void *_h1, void *_h2) |
| static void | timing_shutdown (void) |
| static char * | timing_test (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Variables | |
| static struct ast_cli_entry | cli_timing [] |
| static struct ast_heap * | timing_interfaces |
Timing source management.
Definition in file timing.c.
| void* _ast_register_timing_interface | ( | struct ast_timing_interface * | funcs, |
| struct ast_module * | mod | ||
| ) |
Definition at line 75 of file timing.c.
References ast_calloc, ast_heap_push(), ast_heap_unlock, ast_heap_wrlock, timing_holder::iface, timing_holder::mod, ast_timing_interface::timer_ack, ast_timing_interface::timer_close, ast_timing_interface::timer_disable_continuous, ast_timing_interface::timer_enable_continuous, ast_timing_interface::timer_get_event, ast_timing_interface::timer_get_max_rate, ast_timing_interface::timer_open, and ast_timing_interface::timer_set_rate.
{
struct timing_holder *h;
if (!funcs->timer_open ||
!funcs->timer_close ||
!funcs->timer_set_rate ||
!funcs->timer_ack ||
!funcs->timer_get_event ||
!funcs->timer_get_max_rate ||
!funcs->timer_enable_continuous ||
!funcs->timer_disable_continuous) {
return NULL;
}
if (!(h = ast_calloc(1, sizeof(*h)))) {
return NULL;
}
h->iface = funcs;
h->mod = mod;
ast_heap_wrlock(timing_interfaces);
ast_heap_push(timing_interfaces, h);
ast_heap_unlock(timing_interfaces);
return h;
}
| int ast_timer_ack | ( | const struct ast_timer * | handle, |
| unsigned int | quantity | ||
| ) |
Acknowledge a timer event.
| handle | timer handle returned from timer_open() |
| quantity | number of timer events to acknowledge |
| -1 | failure, with errno set |
| 0 | success |
Definition at line 172 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_ack.
Referenced by __ast_read(), hook_event_cb(), monmp3thread(), softmix_bridge_thread(), spandsp_fax_read(), timing_read(), and timing_test().
| void ast_timer_close | ( | struct ast_timer * | handle | ) |
Close an opened timing handle.
| handle | timer handle returned from timer_open() |
Definition at line 150 of file timing.c.
References ast_free, ast_module_unref(), ast_timer::fd, ast_timer::holder, timing_holder::iface, timing_holder::mod, and ast_timing_interface::timer_close.
Referenced by __unload_module(), ast_channel_destructor(), init_app_class(), jb_framedata_destroy(), load_module(), local_ast_moh_start(), moh_class_destructor(), session_destroy(), softmix_bridge_data_destroy(), and timing_test().
{
handle->holder->iface->timer_close(handle->fd);
handle->fd = -1;
ast_module_unref(handle->holder->mod);
ast_free(handle);
}
| int ast_timer_disable_continuous | ( | const struct ast_timer * | handle | ) |
Disable continuous mode.
| handle | timer handle returned from timer_close() |
| -1 | failure, with errno set |
| 0 | success |
Definition at line 190 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_disable_continuous.
Referenced by __ast_read().
{
int res = -1;
res = handle->holder->iface->timer_disable_continuous(handle->fd);
return res;
}
| int ast_timer_enable_continuous | ( | const struct ast_timer * | handle | ) |
Enable continuous mode.
| handle | timer handle returned from timer_open() |
Continuous mode causes poll() on the timer's fd to immediately return always until continuous mode is disabled.
| -1 | failure, with errno set |
| 0 | success |
Definition at line 181 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_enable_continuous.
Referenced by __ast_queue_frame().
{
int res = -1;
res = handle->holder->iface->timer_enable_continuous(handle->fd);
return res;
}
| int ast_timer_fd | ( | const struct ast_timer * | handle | ) |
Get a poll()-able file descriptor for a timer.
| handle | timer handle returned from timer_open() |
Definition at line 158 of file timing.c.
References ast_timer::fd.
Referenced by __ast_channel_alloc_ap(), jb_framedata_init(), monmp3thread(), network_thread(), softmix_bridge_thread(), spandsp_fax_new(), and timing_test().
{
return handle->fd;
}
| enum ast_timer_event ast_timer_get_event | ( | const struct ast_timer * | handle | ) |
Retrieve timing event.
| handle | timer handle returned by timer_open() |
After poll() indicates that there is input on the timer's fd, this will be called to find out what triggered it.
Definition at line 199 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_get_event.
Referenced by __ast_read().
{
enum ast_timer_event res = -1;
res = handle->holder->iface->timer_get_event(handle->fd);
return res;
}
| unsigned int ast_timer_get_max_rate | ( | const struct ast_timer * | handle | ) |
Get maximum rate supported for a timer.
| handle | timer handle returned by timer_open() |
Definition at line 208 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_get_max_rate.
Referenced by ast_settimeout_full().
{
unsigned int res = 0;
res = handle->holder->iface->timer_get_max_rate(handle->fd);
return res;
}
| const char* ast_timer_get_name | ( | const struct ast_timer * | handle | ) |
Get name of timer in use.
| handle | timer handle returned by timer_open() |
Definition at line 217 of file timing.c.
References ast_timer::holder, timing_holder::iface, and ast_timing_interface::name.
Referenced by __ast_channel_alloc_ap().
| struct ast_timer* ast_timer_open | ( | void | ) | [read] |
Open a timer.
| NULL | on error, with errno set |
| non-NULL | timer handle on success |
Definition at line 123 of file timing.c.
References ast_calloc, ast_heap_peek(), ast_heap_rdlock, ast_heap_unlock, ast_module_ref(), ast_timer::fd, ast_timer::holder, timing_holder::iface, timing_holder::mod, ast_timing_interface::timer_close, and ast_timing_interface::timer_open.
Referenced by __ast_channel_alloc_ap(), init_app_class(), jb_framedata_init(), load_module(), local_ast_moh_start(), softmix_bridge_create(), spandsp_fax_new(), and timing_test().
{
int fd = -1;
struct timing_holder *h;
struct ast_timer *t = NULL;
ast_heap_rdlock(timing_interfaces);
if ((h = ast_heap_peek(timing_interfaces, 1))) {
fd = h->iface->timer_open();
ast_module_ref(h->mod);
}
if (fd != -1) {
if (!(t = ast_calloc(1, sizeof(*t)))) {
h->iface->timer_close(fd);
} else {
t->fd = fd;
t->holder = h;
}
}
ast_heap_unlock(timing_interfaces);
return t;
}
| int ast_timer_set_rate | ( | const struct ast_timer * | handle, |
| unsigned int | rate | ||
| ) |
Set the timing tick rate.
| handle | timer handle returned from timer_open() |
| rate | ticks per second, 0 turns the ticks off if needed |
Use this function if you want the timer to show input at a certain rate. The other alternative use of a timer is the continuous mode.
| -1 | error, with errno set |
| 0 | success |
Definition at line 163 of file timing.c.
References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_set_rate.
Referenced by __ast_read(), ast_settimeout_full(), hook_event_cb(), init_app_class(), jb_framedata_init(), load_module(), local_ast_moh_start(), set_config(), softmix_bridge_thread(), spandsp_fax_start(), and timing_test().
{
int res = -1;
res = handle->holder->iface->timer_set_rate(handle->fd, rate);
return res;
}
| int ast_timing_init | ( | void | ) |
Provided by timing.c
Definition at line 310 of file timing.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_heap_create(), ast_register_atexit(), timing_holder_cmp(), and timing_shutdown().
Referenced by main().
{
if (!(timing_interfaces = ast_heap_create(2, timing_holder_cmp, 0))) {
return -1;
}
ast_register_atexit(timing_shutdown);
return ast_cli_register_multiple(cli_timing, ARRAY_LEN(cli_timing));
}
| int ast_unregister_timing_interface | ( | void * | handle | ) |
Unregister a previously registered timing interface.
| handle | The handle returned from a prior successful call to ast_register_timing_interface(). |
| 0 | success |
| non-zero | failure |
Definition at line 105 of file timing.c.
References ast_free, ast_heap_remove(), ast_heap_unlock, and ast_heap_wrlock.
Referenced by unload_module().
{
struct timing_holder *h = handle;
int res = -1;
ast_heap_wrlock(timing_interfaces);
h = ast_heap_remove(timing_interfaces, h);
ast_heap_unlock(timing_interfaces);
if (h) {
ast_free(h);
h = NULL;
res = 0;
}
return res;
}
| static int timing_holder_cmp | ( | void * | _h1, |
| void * | _h2 | ||
| ) | [static] |
Definition at line 61 of file timing.c.
References timing_holder::iface, and ast_timing_interface::priority.
Referenced by ast_timing_init().
{
struct timing_holder *h1 = _h1;
struct timing_holder *h2 = _h2;
if (h1->iface->priority > h2->iface->priority) {
return 1;
} else if (h1->iface->priority == h2->iface->priority) {
return 0;
} else {
return -1;
}
}
| static void timing_shutdown | ( | void | ) | [static] |
Definition at line 302 of file timing.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), and ast_heap_destroy().
Referenced by ast_timing_init().
| static char* timing_test | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 222 of file timing.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_poll, ast_timer_ack(), ast_timer_close(), ast_timer_fd(), ast_timer_open(), ast_timer_set_rate(), ast_tvdiff_ms(), ast_tvnow(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, errno, ast_cli_args::fd, ast_timer::holder, timing_holder::iface, ast_timing_interface::name, timer, and ast_cli_entry::usage.
{
struct ast_timer *timer;
int count = 0;
struct timeval start, end;
unsigned int test_rate = 50;
switch (cmd) {
case CLI_INIT:
e->command = "timing test";
e->usage = "Usage: timing test <rate>\n"
" Test a timer with a specified rate, 50/sec by default.\n"
"";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 2 && a->argc != 3) {
return CLI_SHOWUSAGE;
}
if (a->argc == 3) {
unsigned int rate;
if (sscanf(a->argv[2], "%30u", &rate) == 1) {
test_rate = rate;
} else {
ast_cli(a->fd, "Invalid rate '%s', using default of %u\n", a->argv[2], test_rate);
}
}
ast_cli(a->fd, "Attempting to test a timer with %u ticks per second.\n", test_rate);
if (!(timer = ast_timer_open())) {
ast_cli(a->fd, "Failed to open timing fd\n");
return CLI_FAILURE;
}
ast_cli(a->fd, "Using the '%s' timing module for this test.\n", timer->holder->iface->name);
start = ast_tvnow();
ast_timer_set_rate(timer, test_rate);
while (ast_tvdiff_ms((end = ast_tvnow()), start) < 1000) {
int res;
struct pollfd pfd = {
.fd = ast_timer_fd(timer),
.events = POLLIN | POLLPRI,
};
res = ast_poll(&pfd, 1, 100);
if (res == 1) {
count++;
if (ast_timer_ack(timer, 1) < 0) {
ast_cli(a->fd, "Timer failed to acknowledge.\n");
ast_timer_close(timer);
return CLI_FAILURE;
}
} else if (!res) {
ast_cli(a->fd, "poll() timed out! This is bad.\n");
} else if (errno != EAGAIN && errno != EINTR) {
ast_cli(a->fd, "poll() returned error: %s\n", strerror(errno));
}
}
ast_timer_close(timer);
timer = NULL;
ast_cli(a->fd, "It has been %" PRIi64 " milliseconds, and we got %d timer ticks\n",
ast_tvdiff_ms(end, start), count);
return CLI_SUCCESS;
}
struct ast_cli_entry cli_timing[] [static] |
{
AST_CLI_DEFINE(timing_test, "Run a timing test"),
}
struct ast_heap* timing_interfaces [static] |