#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_info * | ast_module_info = &__mod_info |
static struct ao2_container * | kqueue_timers |
static struct ast_timing_interface | kqueue_timing |
static void * | timing_funcs_handle |
Definition in file res_timing_kqueue.c.
#define lookup_timer | ( | a | ) | _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().
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 }
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] |
void* timing_funcs_handle [static] |
Definition at line 46 of file res_timing_kqueue.c.