kqueue timing interface More...
#include "asterisk.h"#include <sys/types.h>#include <sys/event.h>#include <sys/time.h>#include "asterisk/module.h"#include "asterisk/astobj2.h"#include "asterisk/timing.h"#include "asterisk/logger.h"#include "asterisk/utils.h"#include "asterisk/time.h"#include "asterisk/test.h"#include "asterisk/poll-compat.h"
Go to the source code of this file.
Data Structures | |
| struct | kqueue_timer |
Defines | |
| #define | lookup_timer(a) _lookup_timer(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static struct kqueue_timer * | _lookup_timer (int handle, const char *file, int line, const char *func) |
| static void | kqueue_set_nsecs (struct kqueue_timer *our_timer, uint64_t nsecs) |
| static int | kqueue_timer_ack (int handle, unsigned int quantity) |
| static void | kqueue_timer_close (int handle) |
| static int | kqueue_timer_cmp (void *obj, void *args, int flags) |
| static int | kqueue_timer_disable_continuous (int handle) |
| static int | kqueue_timer_enable_continuous (int handle) |
| static enum ast_timer_event | kqueue_timer_get_event (int handle) |
| static unsigned int | kqueue_timer_get_max_rate (int handle) |
| static int | kqueue_timer_hash (const void *obj, const int flags) |
| static int | kqueue_timer_open (void) |
| static int | kqueue_timer_set_rate (int handle, unsigned int rate) |
| static int | load_module (void) |
| static void | timer_destroy (void *obj) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "KQueue Timing Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ao2_container * | kqueue_timers |
| static struct ast_timing_interface | kqueue_timing |
| static void * | timing_funcs_handle |
kqueue timing interface
Definition in file res_timing_kqueue.c.
| #define lookup_timer | ( | a | ) | _lookup_timer(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
Definition at line 99 of file res_timing_kqueue.c.
Referenced by kqueue_timer_ack(), kqueue_timer_close(), kqueue_timer_disable_continuous(), kqueue_timer_enable_continuous(), kqueue_timer_get_event(), and kqueue_timer_set_rate().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 400 of file res_timing_kqueue.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 400 of file res_timing_kqueue.c.
| static struct kqueue_timer* _lookup_timer | ( | int | handle, |
| const char * | file, | ||
| int | line, | ||
| const char * | func | ||
| ) | [static, read] |
Definition at line 100 of file res_timing_kqueue.c.
References __LOG_ERROR, ao2_find, ast_log(), errno, kqueue_timer::handle, and OBJ_POINTER.
{
struct kqueue_timer *our_timer, find_helper = {
.handle = handle,
};
if (!(our_timer = ao2_find(kqueue_timers, &find_helper, OBJ_POINTER))) {
ast_log(__LOG_ERROR, file, line, func, "Couldn't find timer with handle %d\n", handle);
/* API says we set errno */
errno = ESRCH;
return NULL;
}
return our_timer;
}
| static void kqueue_set_nsecs | ( | struct kqueue_timer * | our_timer, |
| uint64_t | nsecs | ||
| ) | [static] |
Definition at line 149 of file res_timing_kqueue.c.
References kqueue_timer::handle.
Referenced by kqueue_timer_disable_continuous(), kqueue_timer_enable_continuous(), and kqueue_timer_set_rate().
{
struct timespec nowait = { 0, 1 };
#ifdef HAVE_KEVENT64
struct kevent64_s kev;
EV_SET64(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_NSECONDS,
nsecs, 0, 0, 0);
kevent64(our_timer->handle, &kev, 1, NULL, 0, 0, &nowait);
#else
struct kevent kev;
EV_SET(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE,
#ifdef NOTE_NSECONDS
nsecs <= 0xFFffFFff ? NOTE_NSECONDS :
#endif
#ifdef NOTE_USECONDS
NOTE_USECONDS
#else /* Milliseconds, if no constants are defined */
0
#endif
,
#ifdef NOTE_NSECONDS
nsecs <= 0xFFffFFff ? nsecs :
#endif
#ifdef NOTE_USECONDS
nsecs / 1000
#else /* Milliseconds, if nothing else is defined */
nsecs / 1000000
#endif
, NULL);
kevent(our_timer->handle, &kev, 1, NULL, 0, &nowait);
#endif
}
| static int kqueue_timer_ack | ( | int | handle, |
| unsigned int | quantity | ||
| ) | [static] |
Definition at line 198 of file res_timing_kqueue.c.
References ao2_ref, ast_debug, lookup_timer, and kqueue_timer::unacked.
{
struct kqueue_timer *our_timer;
if (!(our_timer = lookup_timer(handle))) {
return -1;
}
if (our_timer->unacked < quantity) {
ast_debug(1, "Acking more events than have expired?!!\n");
our_timer->unacked = 0;
ao2_ref(our_timer, -1);
return -1;
} else {
our_timer->unacked -= quantity;
}
ao2_ref(our_timer, -1);
return 0;
}
| static void kqueue_timer_close | ( | int | handle | ) | [static] |
Definition at line 137 of file res_timing_kqueue.c.
References ao2_ref, ao2_unlink, and lookup_timer.
{
struct kqueue_timer *our_timer;
if (!(our_timer = lookup_timer(handle))) {
return;
}
ao2_unlink(kqueue_timers, our_timer);
ao2_ref(our_timer, -1);
}
| static int kqueue_timer_cmp | ( | void * | obj, |
| void * | args, | ||
| int | flags | ||
| ) | [static] |
Definition at line 87 of file res_timing_kqueue.c.
References args, CMP_MATCH, CMP_STOP, and kqueue_timer::handle.
Referenced by load_module().
{
struct kqueue_timer *timer1 = obj, *timer2 = args;
return timer1->handle == timer2->handle ? CMP_MATCH | CMP_STOP : 0;
}
| static int kqueue_timer_disable_continuous | ( | int | handle | ) | [static] |
Definition at line 234 of file res_timing_kqueue.c.
References ao2_ref, kqueue_timer::is_continuous, kqueue_set_nsecs(), lookup_timer, kqueue_timer::nsecs, and kqueue_timer::unacked.
{
struct kqueue_timer *our_timer;
if (!(our_timer = lookup_timer(handle))) {
return -1;
}
kqueue_set_nsecs(our_timer, our_timer->nsecs);
our_timer->is_continuous = 0;
our_timer->unacked = 0;
ao2_ref(our_timer, -1);
return 0;
}
| static int kqueue_timer_enable_continuous | ( | int | handle | ) | [static] |
Definition at line 219 of file res_timing_kqueue.c.
References ao2_ref, kqueue_timer::is_continuous, kqueue_set_nsecs(), lookup_timer, and kqueue_timer::unacked.
{
struct kqueue_timer *our_timer;
if (!(our_timer = lookup_timer(handle))) {
return -1;
}
kqueue_set_nsecs(our_timer, 1);
our_timer->is_continuous = 1;
our_timer->unacked = 0;
ao2_ref(our_timer, -1);
return 0;
}
| static enum ast_timer_event kqueue_timer_get_event | ( | int | handle | ) | [static] |
Definition at line 249 of file res_timing_kqueue.c.
References ao2_ref, AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, kqueue_timer::is_continuous, lookup_timer, and kqueue_timer::unacked.
{
enum ast_timer_event res = -1;
struct kqueue_timer *our_timer;
struct timespec sixty_seconds = { 60, 0 };
struct kevent kev;
if (!(our_timer = lookup_timer(handle))) {
return -1;
}
/* If we have non-ACKed events, just return immediately */
if (our_timer->unacked == 0) {
if (kevent(handle, NULL, 0, &kev, 1, &sixty_seconds) > 0) {
our_timer->unacked += kev.data;
}
}
if (our_timer->unacked > 0) {
res = our_timer->is_continuous ? AST_TIMING_EVENT_CONTINUOUS : AST_TIMING_EVENT_EXPIRED;
}
ao2_ref(our_timer, -1);
return res;
}
| static unsigned int kqueue_timer_get_max_rate | ( | int | handle | ) | [static] |
Definition at line 275 of file res_timing_kqueue.c.
{
/* Actually, the max rate is 2^64-1 seconds, but that's not representable in a 32-bit integer. */
return UINT_MAX;
}
| static int kqueue_timer_hash | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 80 of file res_timing_kqueue.c.
References kqueue_timer::handle, and timer.
Referenced by load_module().
{
const struct kqueue_timer *timer = obj;
return timer->handle;
}
| static int kqueue_timer_open | ( | void | ) | [static] |
Definition at line 115 of file res_timing_kqueue.c.
References ao2_alloc, ao2_link, ao2_ref, ast_log(), errno, kqueue_timer::handle, LOG_ERROR, timer, and timer_destroy().
{
struct kqueue_timer *timer;
int handle;
if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
ast_log(LOG_ERROR, "Could not allocate memory for kqueue_timer structure\n");
return -1;
}
if ((handle = kqueue()) < 0) {
ast_log(LOG_ERROR, "Failed to create kqueue timer: %s\n", strerror(errno));
ao2_ref(timer, -1);
return -1;
}
timer->handle = handle;
ao2_link(kqueue_timers, timer);
/* Get rid of the reference from the allocation */
ao2_ref(timer, -1);
return handle;
}
| static int kqueue_timer_set_rate | ( | int | handle, |
| unsigned int | rate | ||
| ) | [static] |
Definition at line 184 of file res_timing_kqueue.c.
References ao2_ref, kqueue_set_nsecs(), lookup_timer, and kqueue_timer::nsecs.
{
struct kqueue_timer *our_timer;
if (!(our_timer = lookup_timer(handle))) {
return -1;
}
kqueue_set_nsecs(our_timer, (our_timer->nsecs = rate ? (long) (1000000000 / rate) : 0L));
ao2_ref(our_timer, -1);
return 0;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 368 of file res_timing_kqueue.c.
References ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_timing_interface, AST_TEST_REGISTER, kqueue_timer_cmp(), kqueue_timer_hash(), and timing_funcs_handle.
{
if (!(kqueue_timers = ao2_container_alloc(563, kqueue_timer_hash, kqueue_timer_cmp))) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(timing_funcs_handle = ast_register_timing_interface(&kqueue_timing))) {
ao2_ref(kqueue_timers, -1);
return AST_MODULE_LOAD_DECLINE;
}
AST_TEST_REGISTER(test_kqueue_timing);
return AST_MODULE_LOAD_SUCCESS;
}
| static void timer_destroy | ( | void * | obj | ) | [static] |
Definition at line 93 of file res_timing_kqueue.c.
References kqueue_timer::handle, and timer.
Referenced by kqueue_timer_open().
{
struct kqueue_timer *timer = obj;
close(timer->handle);
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 383 of file res_timing_kqueue.c.
References ao2_ref, AST_TEST_UNREGISTER, ast_unregister_timing_interface(), and timing_funcs_handle.
{
int res;
AST_TEST_UNREGISTER(test_kqueue_timing);
if (!(res = ast_unregister_timing_interface(timing_funcs_handle))) {
ao2_ref(kqueue_timers, -1);
kqueue_timers = NULL;
}
return res;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "KQueue Timing Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static] |
Definition at line 400 of file res_timing_kqueue.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 400 of file res_timing_kqueue.c.
struct ao2_container* kqueue_timers [static] |
Definition at line 71 of file res_timing_kqueue.c.
struct ast_timing_interface kqueue_timing [static] |
Definition at line 58 of file res_timing_kqueue.c.
void* timing_funcs_handle [static] |
Definition at line 47 of file res_timing_kqueue.c.
Referenced by load_module(), and unload_module().