Tue Aug 20 16:35:14 2013

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 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 = "ac1f6a56484a8820659555499174e588" , .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__)

Function Documentation

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.

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

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().

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

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.

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

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.

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

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

Definition at line 87 of file res_timing_kqueue.c.

References CMP_MATCH, CMP_STOP, and kqueue_timer::handle.

Referenced by load_module().

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

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.

00235 {
00236    struct kqueue_timer *our_timer;
00237 
00238    if (!(our_timer = lookup_timer(handle))) {
00239       return -1;
00240    }
00241 
00242    kqueue_set_nsecs(our_timer, our_timer->nsecs);
00243    our_timer->is_continuous = 0;
00244    our_timer->unacked = 0;
00245    ao2_ref(our_timer, -1);
00246    return 0;
00247 }

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.

00220 {
00221    struct kqueue_timer *our_timer;
00222 
00223    if (!(our_timer = lookup_timer(handle))) {
00224       return -1;
00225    }
00226 
00227    kqueue_set_nsecs(our_timer, 1);
00228    our_timer->is_continuous = 1;
00229    our_timer->unacked = 0;
00230    ao2_ref(our_timer, -1);
00231    return 0;
00232 }

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.

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

static unsigned int kqueue_timer_get_max_rate ( int  handle  )  [static]

Definition at line 275 of file res_timing_kqueue.c.

00276 {
00277    /* Actually, the max rate is 2^64-1 seconds, but that's not representable in a 32-bit integer. */
00278    return UINT_MAX;
00279 }

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().

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

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().

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

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.

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

static int load_module ( void   )  [static]
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().

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

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.

00384 {
00385    int res;
00386 
00387    AST_TEST_UNREGISTER(test_kqueue_timing);
00388    if (!(res = ast_unregister_timing_interface(timing_funcs_handle))) {
00389       ao2_ref(kqueue_timers, -1);
00390       kqueue_timers = NULL;
00391    }
00392 
00393    return res;
00394 }


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

Definition at line 400 of file res_timing_kqueue.c.

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.

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().


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1