Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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.
 
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 = ASTERISK_GPL_KEY , .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:388
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
#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, 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, 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, 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 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, 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 = ASTERISK_GPL_KEY , .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.

61 {
62 .name = "kqueue",
63 .priority = 150,
64 .timer_open = kqueue_timer_open,
65 .timer_close = kqueue_timer_close,
66 .timer_set_rate = kqueue_timer_set_rate,
67 .timer_ack = kqueue_timer_ack,
68 .timer_enable_continuous = kqueue_timer_enable_continuous,
69 .timer_disable_continuous = kqueue_timer_disable_continuous,
70 .timer_get_event = kqueue_timer_get_event,
71 .timer_get_max_rate = kqueue_timer_get_max_rate,
72 .timer_fd = kqueue_timer_fd,
73};
static void kqueue_timer_close(void *data)
static int kqueue_timer_disable_continuous(void *data)
static int kqueue_timer_set_rate(void *data, unsigned int rate)
static enum ast_timer_event kqueue_timer_get_event(void *data)
static void * kqueue_timer_open(void)
static int kqueue_timer_fd(void *data)
static int kqueue_timer_ack(void *data, unsigned int quantity)
static unsigned int kqueue_timer_get_max_rate(void *data)
static int kqueue_timer_enable_continuous(void *data)

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