Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
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"
Include dependency graph for res_timing_kqueue.c:

Go to the source code of this file.

Data Structures

struct  kqueue_timer
 

Macros

#define CONTINUOUS_EVFILT_TYPE   EVFILT_READ
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static intptr_t kqueue_scale_period (unsigned int period_ns, int *units)
 
static int kqueue_timer_ack (void *data, unsigned int quantity)
 
static void kqueue_timer_close (void *data)
 
static int kqueue_timer_disable_continuous (void *data)
 
static int kqueue_timer_disable_continuous_event (struct kqueue_timer *timer)
 
static int kqueue_timer_enable_continuous (void *data)
 
static int kqueue_timer_enable_continuous_event (struct kqueue_timer *timer)
 
static int kqueue_timer_fd (void *data)
 
static void kqueue_timer_fini_continuous_event (struct kqueue_timer *timer)
 
static enum ast_timer_event kqueue_timer_get_event (void *data)
 
static unsigned int kqueue_timer_get_max_rate (void *data)
 
static int kqueue_timer_init_continuous_event (struct kqueue_timer *timer)
 
static void * kqueue_timer_open (void)
 
static int kqueue_timer_set_rate (void *data, unsigned int rate)
 
static int load_module (void)
 Load the module. More...
 
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, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
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.

Macro Definition Documentation

◆ CONTINUOUS_EVFILT_TYPE

#define CONTINUOUS_EVFILT_TYPE   EVFILT_READ

Definition at line 117 of file res_timing_kqueue.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 508 of file res_timing_kqueue.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 508 of file res_timing_kqueue.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 508 of file res_timing_kqueue.c.

◆ kqueue_scale_period()

static intptr_t kqueue_scale_period ( unsigned int  period_ns,
int *  units 
)
static

Definition at line 205 of file res_timing_kqueue.c.

206{
207 uint64_t period = period_ns;
208 *units = 0;
209#ifdef NOTE_NSECONDS
210 if (period < INTPTR_MAX) {
211 *units = NOTE_NSECONDS;
212 } else {
213#ifdef NOTE_USECONDS
214 period /= 1000;
215 if (period < INTPTR_MAX) {
216 *units = NOTE_USECONDS;
217 } else {
218 period /= 1000;
219#ifdef NOTE_MSECONDS
220 *units = NOTE_MSECONDS;
221#endif /* NOTE_MSECONDS */
222 }
223#else /* NOTE_USECONDS */
224 period /= 1000000;
225#ifdef NOTE_MSECONDS
226 *units = NOTE_MSECONDS;
227#endif /* NOTE_MSECONDS */
228#endif /* NOTE_USECONDS */
229 }
230#else /* NOTE_NSECONDS */
231 period /= 1000000;
232#endif
233 if (period > INTPTR_MAX) {
234 period = INTPTR_MAX;
235 }
236 return period;
237}

References kqueue_timer::period.

Referenced by kqueue_timer_set_rate().

◆ kqueue_timer_ack()

static int kqueue_timer_ack ( void *  data,
unsigned int  quantity 
)
static

Definition at line 279 of file res_timing_kqueue.c.

280{
281 static struct timespec ts_nowait = { 0, 0 };
282 struct kqueue_timer *timer = data;
283 struct kevent kev[2];
284 int i, retval;
285
287
288 retval = kevent(timer->handle, NULL, 0, kev, 2, &ts_nowait);
289 if (retval == -1) {
290 ast_log(LOG_ERROR, "[%d]: Error sampling kqueue: %s\n",
291 timer->handle, strerror(errno));
293 return -1;
294 }
295
296 for (i = 0; i < retval; i++) {
297 switch (kev[i].filter) {
298 case EVFILT_TIMER:
299 if (kev[i].data > quantity) {
300 ast_log(LOG_ERROR, "[%d]: Missed %ju\n",
301 timer->handle,
302 (uintmax_t)kev[i].data - quantity);
303 }
304 break;
306 if (!timer->is_continuous) {
308 "[%d]: Spurious user event\n",
309 timer->handle);
310 }
311 break;
312 default:
313 ast_log(LOG_ERROR, "[%d]: Spurious kevent type %d.\n",
314 timer->handle, kev[i].filter);
315 }
316 }
317
319
320 return 0;
321}
#define ast_log
Definition: astobj2.c:42
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
static struct ast_timer * timer
Definition: chan_iax2.c:364
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
static ENTRY retval
Definition: hsearch.c:50
#define LOG_ERROR
int errno
#define CONTINUOUS_EVFILT_TYPE
#define NULL
Definition: resample.c:96
void * data
Definition: timing.c:55

References ao2_lock, ao2_unlock, ast_log, CONTINUOUS_EVFILT_TYPE, ast_timer::data, errno, filter(), LOG_ERROR, NULL, retval, and timer.

◆ kqueue_timer_close()

static void kqueue_timer_close ( void *  data)
static

Definition at line 193 of file res_timing_kqueue.c.

194{
195 struct kqueue_timer *timer = data;
196
197 ast_debug(5, "[%d]: Timer Close\n", timer->handle);
198 ao2_ref(timer, -1);
199}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_debug(level,...)
Log a DEBUG message.

References ao2_ref, ast_debug, and timer.

◆ kqueue_timer_disable_continuous()

static int kqueue_timer_disable_continuous ( void *  data)
static

Definition at line 346 of file res_timing_kqueue.c.

347{
348 struct kqueue_timer *timer = data;
349 int retval;
350
352
353 if (timer->is_continuous) {
354 ast_debug(5, "[%d]: Disable Continuous\n", timer->handle);
356 if (retval == -1) {
358 "[%d]: Error clearing continuous event: %s\n",
359 timer->handle, strerror(errno));
360 }
361 timer->is_continuous = 0;
362 }
363
365
366 return 0;
367}
static int kqueue_timer_disable_continuous_event(struct kqueue_timer *timer)

References ao2_lock, ao2_unlock, ast_debug, ast_log, errno, kqueue_timer_disable_continuous_event(), LOG_ERROR, retval, and timer.

◆ kqueue_timer_disable_continuous_event()

static int kqueue_timer_disable_continuous_event ( struct kqueue_timer timer)
static

Definition at line 148 of file res_timing_kqueue.c.

149{
150 struct kevent kev;
151
152 EV_SET(&kev, timer->continuous_fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
153 return kevent(timer->handle, &kev, 1, NULL, 0, NULL);
154}

References NULL, and timer.

Referenced by kqueue_timer_disable_continuous().

◆ kqueue_timer_enable_continuous()

static int kqueue_timer_enable_continuous ( void *  data)
static

Definition at line 323 of file res_timing_kqueue.c.

324{
325 struct kqueue_timer *timer = data;
326 int retval;
327
329
330 if (!timer->is_continuous) {
331 ast_debug(5, "[%d]: Enable Continuous\n", timer->handle);
333 if (retval == -1) {
335 "[%d]: Error signaling continuous event: %s\n",
336 timer->handle, strerror(errno));
337 }
338 timer->is_continuous = 1;
339 }
340
342
343 return 0;
344}
static int kqueue_timer_enable_continuous_event(struct kqueue_timer *timer)

References ao2_lock, ao2_unlock, ast_debug, ast_log, errno, kqueue_timer_enable_continuous_event(), LOG_ERROR, retval, and timer.

◆ kqueue_timer_enable_continuous_event()

static int kqueue_timer_enable_continuous_event ( struct kqueue_timer timer)
static

Definition at line 139 of file res_timing_kqueue.c.

140{
141 struct kevent kev;
142
143 EV_SET(&kev, timer->continuous_fd, EVFILT_READ, EV_ADD | EV_ENABLE,
144 0, 0, NULL);
145 return kevent(timer->handle, &kev, 1, NULL, 0, NULL);
146}

References NULL, and timer.

Referenced by kqueue_timer_enable_continuous().

◆ kqueue_timer_fd()

static int kqueue_timer_fd ( void *  data)
static

Definition at line 388 of file res_timing_kqueue.c.

389{
390 struct kqueue_timer *timer = data;
391
392 return timer->handle;
393}

References timer.

◆ kqueue_timer_fini_continuous_event()

static void kqueue_timer_fini_continuous_event ( struct kqueue_timer timer)
static

Definition at line 132 of file res_timing_kqueue.c.

133{
134 if (timer->continuous_fd_valid) {
135 close(timer->continuous_fd);
136 }
137}

References timer.

Referenced by timer_destroy().

◆ kqueue_timer_get_event()

static enum ast_timer_event kqueue_timer_get_event ( void *  data)
static

Definition at line 369 of file res_timing_kqueue.c.

370{
371 struct kqueue_timer *timer = data;
372 enum ast_timer_event res;
373
374 if (timer->is_continuous) {
376 } else {
378 }
379
380 return res;
381}
ast_timer_event
Definition: timing.h:57
@ AST_TIMING_EVENT_CONTINUOUS
Definition: timing.h:59
@ AST_TIMING_EVENT_EXPIRED
Definition: timing.h:58

References AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, and timer.

◆ kqueue_timer_get_max_rate()

static unsigned int kqueue_timer_get_max_rate ( void *  data)
static

Definition at line 383 of file res_timing_kqueue.c.

384{
385 return INTPTR_MAX > UINT_MAX ? UINT_MAX : INTPTR_MAX;
386}

◆ kqueue_timer_init_continuous_event()

static int kqueue_timer_init_continuous_event ( struct kqueue_timer timer)
static

Definition at line 118 of file res_timing_kqueue.c.

119{
120 int pipefds[2];
121 int retval;
122
123 retval = pipe(pipefds);
124 if (retval == 0) {
125 timer->continuous_fd = pipefds[0];
126 timer->continuous_fd_valid = 1;
127 close(pipefds[1]);
128 }
129 return retval;
130}

References retval, and timer.

Referenced by kqueue_timer_open().

◆ kqueue_timer_open()

static void * kqueue_timer_open ( void  )
static

Definition at line 167 of file res_timing_kqueue.c.

168{
169 struct kqueue_timer *timer;
170
171 if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
172 ast_log(LOG_ERROR, "Alloc failed for kqueue_timer structure\n");
173 return NULL;
174 }
175
176 if ((timer->handle = kqueue()) < 0) {
177 ast_log(LOG_ERROR, "Failed to create kqueue fd: %s\n",
178 strerror(errno));
179 ao2_ref(timer, -1);
180 return NULL;
181 }
182
184 ast_log(LOG_ERROR, "Failed to create continuous event: %s\n",
185 strerror(errno));
186 ao2_ref(timer, -1);
187 return NULL;
188 }
189 ast_debug(5, "[%d]: Create timer\n", timer->handle);
190 return timer;
191}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static int kqueue_timer_init_continuous_event(struct kqueue_timer *timer)
static void timer_destroy(void *obj)

References ao2_alloc, ao2_ref, ast_debug, ast_log, errno, kqueue_timer_init_continuous_event(), LOG_ERROR, NULL, timer, and timer_destroy().

◆ kqueue_timer_set_rate()

static int kqueue_timer_set_rate ( void *  data,
unsigned int  rate 
)
static

Definition at line 239 of file res_timing_kqueue.c.

240{
241 struct kevent kev;
242 struct kqueue_timer *timer = data;
243 uint64_t period_ns;
244 int flags;
245 int units;
246 int retval;
247
249
250 if (rate == 0) {
251 if (timer->period == 0) {
253 return (0);
254 }
255 flags = EV_DELETE;
256 timer->period = 0;
257 units = 0;
258 } else {
259 flags = EV_ADD | EV_ENABLE;
260 period_ns = (uint64_t)1000000000 / rate;
261 timer->period = kqueue_scale_period(period_ns, &units);
262 }
263 ast_debug(5, "[%d]: Set rate %u:%ju\n",
264 timer->handle, units, (uintmax_t)timer->period);
265 EV_SET(&kev, timer->handle, EVFILT_TIMER, flags, units,
266 timer->period, NULL);
267 retval = kevent(timer->handle, &kev, 1, NULL, 0, NULL);
268
269 if (retval == -1) {
270 ast_log(LOG_ERROR, "[%d]: Error queing timer: %s\n",
271 timer->handle, strerror(errno));
272 }
273
275
276 return 0;
277}
static intptr_t kqueue_scale_period(unsigned int period_ns, int *units)

References ao2_lock, ao2_unlock, ast_debug, ast_log, errno, kqueue_scale_period(), LOG_ERROR, NULL, retval, and timer.

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 486 of file res_timing_kqueue.c.

487{
490 }
491
492 AST_TEST_REGISTER(test_kqueue_timing);
494}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static void * timing_funcs_handle
static struct ast_timing_interface kqueue_timing
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition: timing.h:95

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_timing_interface, AST_TEST_REGISTER, kqueue_timing, and timing_funcs_handle.

◆ timer_destroy()

static void timer_destroy ( void *  obj)
static

Definition at line 157 of file res_timing_kqueue.c.

158{
159 struct kqueue_timer *timer = obj;
160 ast_debug(5, "[%d]: Timer Destroy\n", timer->handle);
162 if (timer->handle > -1) {
163 close(timer->handle);
164 }
165}
static void kqueue_timer_fini_continuous_event(struct kqueue_timer *timer)

References ast_debug, kqueue_timer_fini_continuous_event(), and timer.

Referenced by kqueue_timer_open().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 496 of file res_timing_kqueue.c.

497{
498 AST_TEST_UNREGISTER(test_kqueue_timing);
499
501}
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
int ast_unregister_timing_interface(void *handle)
Unregister a previously registered timing interface.
Definition: timing.c:104

References AST_TEST_UNREGISTER, ast_unregister_timing_interface(), and timing_funcs_handle.

Variable Documentation

◆ __mod_info

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, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 508 of file res_timing_kqueue.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 508 of file res_timing_kqueue.c.

◆ kqueue_timing

struct ast_timing_interface kqueue_timing
static

Definition at line 61 of file res_timing_kqueue.c.

Referenced by load_module().

◆ timing_funcs_handle

void* timing_funcs_handle
static

Definition at line 49 of file res_timing_kqueue.c.

Referenced by load_module(), and unload_module().