Wed Apr 6 11:30:09 2011

Asterisk developer's documentation


res_timing_kqueue.c File Reference

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 void 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ao2_containerkqueue_timers
static struct ast_timing_interface kqueue_timing
static void * timing_funcs_handle


Detailed Description

kqueue timing interface

Author:
Tilghman Lesher <tlesher at="" digium="" dot="" com>="">

Definition in file res_timing_kqueue.c.


Define Documentation

#define lookup_timer (  )     _lookup_timer(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 98 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().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 394 of file res_timing_kqueue.c.

static void __unreg_module ( void   )  [static]

Definition at line 394 of file res_timing_kqueue.c.

static struct kqueue_timer* _lookup_timer ( int  handle,
const char *  file,
int  line,
const char *  func 
) [static]

Definition at line 99 of file res_timing_kqueue.c.

References __LOG_ERROR, ao2_find, ast_log(), errno, kqueue_timer::handle, kqueue_timers, and OBJ_POINTER.

00100 {
00101    struct kqueue_timer *our_timer, find_helper = {
00102       .handle = handle,
00103    };
00104 
00105    if (!(our_timer = ao2_find(kqueue_timers, &find_helper, OBJ_POINTER))) {
00106       ast_log(__LOG_ERROR, file, line, func, "Couldn't find timer with handle %d\n", handle);
00107       /* API says we set errno */
00108       errno = ESRCH;
00109       return NULL;
00110    }
00111    return our_timer;
00112 }

static void kqueue_set_nsecs ( struct kqueue_timer our_timer,
uint64_t  nsecs 
) [static]

Definition at line 148 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().

00149 {
00150    struct timespec nowait = { 0, 1 };
00151 #ifdef HAVE_KEVENT64
00152    struct kevent64_s kev;
00153 
00154    EV_SET64(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_NSECONDS,
00155       nsecs, 0, 0, 0);
00156    kevent64(our_timer->handle, &kev, 1, NULL, 0, 0, &nowait);
00157 #else
00158    struct kevent kev;
00159 
00160    EV_SET(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE,
00161 #ifdef NOTE_NSECONDS
00162       nsecs <= 0xFFffFFff ? NOTE_NSECONDS :
00163 #endif
00164 #ifdef NOTE_USECONDS
00165       NOTE_USECONDS
00166 #else /* Milliseconds, if no constants are defined */
00167       0
00168 #endif
00169       ,
00170 #ifdef NOTE_NSECONDS
00171       nsecs <= 0xFFffFFff ? nsecs :
00172 #endif
00173 #ifdef NOTE_USECONDS
00174    nsecs / 1000
00175 #else /* Milliseconds, if nothing else is defined */
00176    nsecs / 1000000
00177 #endif
00178    , NULL);
00179    kevent(our_timer->handle, &kev, 1, NULL, 0, &nowait);
00180 #endif
00181 }

static void kqueue_timer_ack ( int  handle,
unsigned int  quantity 
) [static]

Definition at line 197 of file res_timing_kqueue.c.

References ast_debug, lookup_timer, and kqueue_timer::unacked.

00198 {
00199    struct kqueue_timer *our_timer;
00200 
00201    if (!(our_timer = lookup_timer(handle))) {
00202       return;
00203    }
00204 
00205    if (our_timer->unacked < quantity) {
00206       ast_debug(1, "Acking more events than have expired?!!\n");
00207       our_timer->unacked = 0;
00208    } else {
00209       our_timer->unacked -= quantity;
00210    }
00211 }

static void kqueue_timer_close ( int  handle  )  [static]

Definition at line 136 of file res_timing_kqueue.c.

References ao2_ref, ao2_unlink, kqueue_timers, and lookup_timer.

00137 {
00138    struct kqueue_timer *our_timer;
00139 
00140    if (!(our_timer = lookup_timer(handle))) {
00141       return;
00142    }
00143 
00144    ao2_unlink(kqueue_timers, our_timer);
00145    ao2_ref(our_timer, -1);
00146 }

static int kqueue_timer_cmp ( void *  obj,
void *  args,
int  flags 
) [static]

Definition at line 86 of file res_timing_kqueue.c.

References CMP_MATCH, CMP_STOP, and kqueue_timer::handle.

Referenced by load_module().

00087 {
00088    struct kqueue_timer *timer1 = obj, *timer2 = args;
00089    return timer1->handle == timer2->handle ? CMP_MATCH | CMP_STOP : 0;
00090 }

static int kqueue_timer_disable_continuous ( int  handle  )  [static]

Definition at line 228 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.

00229 {
00230    struct kqueue_timer *our_timer;
00231 
00232    if (!(our_timer = lookup_timer(handle))) {
00233       return -1;
00234    }
00235 
00236    kqueue_set_nsecs(our_timer, our_timer->nsecs);
00237    our_timer->is_continuous = 0;
00238    our_timer->unacked = 0;
00239    ao2_ref(our_timer, -1);
00240    return 0;
00241 }

static int kqueue_timer_enable_continuous ( int  handle  )  [static]

Definition at line 213 of file res_timing_kqueue.c.

References ao2_ref, kqueue_timer::is_continuous, kqueue_set_nsecs(), lookup_timer, and kqueue_timer::unacked.

00214 {
00215    struct kqueue_timer *our_timer;
00216 
00217    if (!(our_timer = lookup_timer(handle))) {
00218       return -1;
00219    }
00220 
00221    kqueue_set_nsecs(our_timer, 1);
00222    our_timer->is_continuous = 1;
00223    our_timer->unacked = 0;
00224    ao2_ref(our_timer, -1);
00225    return 0;
00226 }

static enum ast_timer_event kqueue_timer_get_event ( int  handle  )  [static]

Definition at line 243 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.

00244 {
00245    enum ast_timer_event res = -1;
00246    struct kqueue_timer *our_timer;
00247    struct timespec sixty_seconds = { 60, 0 };
00248    struct kevent kev;
00249 
00250    if (!(our_timer = lookup_timer(handle))) {
00251       return -1;
00252    }
00253 
00254    /* If we have non-ACKed events, just return immediately */
00255    if (our_timer->unacked == 0) {
00256       if (kevent(handle, NULL, 0, &kev, 1, &sixty_seconds) > 0) {
00257          our_timer->unacked += kev.data;
00258       }
00259    }
00260 
00261    if (our_timer->unacked > 0) {
00262       res = our_timer->is_continuous ? AST_TIMING_EVENT_CONTINUOUS : AST_TIMING_EVENT_EXPIRED;
00263    }
00264 
00265    ao2_ref(our_timer, -1);
00266    return res;
00267 }

static unsigned int kqueue_timer_get_max_rate ( int  handle  )  [static]

Definition at line 269 of file res_timing_kqueue.c.

00270 {
00271    /* Actually, the max rate is 2^64-1 seconds, but that's not representable in a 32-bit integer. */
00272    return UINT_MAX;
00273 }

static int kqueue_timer_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 79 of file res_timing_kqueue.c.

References timer.

Referenced by load_module().

00080 {
00081    const struct kqueue_timer *timer = obj;
00082 
00083    return timer->handle;
00084 }

static int kqueue_timer_open ( void   )  [static]

Definition at line 114 of file res_timing_kqueue.c.

References ao2_alloc, ao2_link, ao2_ref, ast_log(), errno, kqueue_timer::handle, kqueue_timers, LOG_ERROR, timer, and timer_destroy().

00115 {
00116    struct kqueue_timer *timer;
00117    int handle;
00118 
00119    if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
00120       ast_log(LOG_ERROR, "Could not allocate memory for kqueue_timer structure\n");
00121       return -1;
00122    }
00123    if ((handle = kqueue()) < 0) {
00124       ast_log(LOG_ERROR, "Failed to create kqueue timer: %s\n", strerror(errno));
00125       ao2_ref(timer, -1);
00126       return -1;
00127    }
00128 
00129    timer->handle = handle;
00130    ao2_link(kqueue_timers, timer);
00131    /* Get rid of the reference from the allocation */
00132    ao2_ref(timer, -1);
00133    return handle;
00134 }

static int kqueue_timer_set_rate ( int  handle,
unsigned int  rate 
) [static]

Definition at line 183 of file res_timing_kqueue.c.

References ao2_ref, kqueue_set_nsecs(), lookup_timer, and kqueue_timer::nsecs.

00184 {
00185    struct kqueue_timer *our_timer;
00186 
00187    if (!(our_timer = lookup_timer(handle))) {
00188       return -1;
00189    }
00190 
00191    kqueue_set_nsecs(our_timer, (our_timer->nsecs = rate ? (long) (1000000000 / rate) : 0L));
00192    ao2_ref(our_timer, -1);
00193 
00194    return 0;
00195 }

static int load_module ( void   )  [static]

Definition at line 362 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(), kqueue_timers, kqueue_timing, and timing_funcs_handle.

00363 {
00364    if (!(kqueue_timers = ao2_container_alloc(563, kqueue_timer_hash, kqueue_timer_cmp))) {
00365       return AST_MODULE_LOAD_DECLINE;
00366    }
00367 
00368    if (!(timing_funcs_handle = ast_register_timing_interface(&kqueue_timing))) {
00369       ao2_ref(kqueue_timers, -1);
00370       return AST_MODULE_LOAD_DECLINE;
00371    }
00372 
00373    AST_TEST_REGISTER(test_kqueue_timing);
00374    return AST_MODULE_LOAD_SUCCESS;
00375 }

static void timer_destroy ( void *  obj  )  [static]

Definition at line 92 of file res_timing_kqueue.c.

References timer.

Referenced by kqueue_timer_open(), and timerfd_timer_open().

00093 {
00094    struct kqueue_timer *timer = obj;
00095    close(timer->handle);
00096 }

static int unload_module ( void   )  [static]

Definition at line 377 of file res_timing_kqueue.c.

References ao2_ref, AST_TEST_UNREGISTER, ast_unregister_timing_interface(), kqueue_timers, and timing_funcs_handle.

00378 {
00379    int res;
00380 
00381    AST_TEST_UNREGISTER(test_kqueue_timing);
00382    if (!(res = ast_unregister_timing_interface(timing_funcs_handle))) {
00383       ao2_ref(kqueue_timers, -1);
00384       kqueue_timers = NULL;
00385    }
00386 
00387    return res;
00388 }


Variable Documentation

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static]

Definition at line 394 of file res_timing_kqueue.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 394 of file res_timing_kqueue.c.

struct ao2_container* kqueue_timers [static]

Definition at line 70 of file res_timing_kqueue.c.

Referenced by _lookup_timer(), kqueue_timer_close(), kqueue_timer_open(), load_module(), and unload_module().

struct ast_timing_interface kqueue_timing [static]

Definition at line 57 of file res_timing_kqueue.c.

Referenced by load_module().

void* timing_funcs_handle [static]

Definition at line 46 of file res_timing_kqueue.c.


Generated on Wed Apr 6 11:30:09 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7