Wed Jan 8 2020 09:50:19

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
 

Macros

#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.

Macro Definition Documentation

#define lookup_timer (   a)    _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

Definition at line 100 of file res_timing_kqueue.c.

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

101 {
102  struct kqueue_timer *our_timer, find_helper = {
103  .handle = handle,
104  };
105 
106  if (!(our_timer = ao2_find(kqueue_timers, &find_helper, OBJ_POINTER))) {
107  ast_log(__LOG_ERROR, file, line, func, "Couldn't find timer with handle %d\n", handle);
108  /* API says we set errno */
109  errno = ESRCH;
110  return NULL;
111  }
112  return our_timer;
113 }
#define __LOG_ERROR
Definition: logger.h:154
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
int errno
static struct ao2_container * kqueue_timers
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().

150 {
151  struct timespec nowait = { 0, 1 };
152 #ifdef HAVE_KEVENT64
153  struct kevent64_s kev;
154 
155  EV_SET64(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_NSECONDS,
156  nsecs, 0, 0, 0);
157  kevent64(our_timer->handle, &kev, 1, NULL, 0, 0, &nowait);
158 #else
159  struct kevent kev;
160 
161  EV_SET(&kev, our_timer->handle, EVFILT_TIMER, EV_ADD | EV_ENABLE,
162 #ifdef NOTE_NSECONDS
163  nsecs <= 0xFFffFFff ? NOTE_NSECONDS :
164 #endif
165 #ifdef NOTE_USECONDS
166  NOTE_USECONDS
167 #else /* Milliseconds, if no constants are defined */
168  0
169 #endif
170  ,
171 #ifdef NOTE_NSECONDS
172  nsecs <= 0xFFffFFff ? nsecs :
173 #endif
174 #ifdef NOTE_USECONDS
175  nsecs / 1000
176 #else /* Milliseconds, if nothing else is defined */
177  nsecs / 1000000
178 #endif
179  , NULL);
180  kevent(our_timer->handle, &kev, 1, NULL, 0, &nowait);
181 #endif
182 }
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.

199 {
200  struct kqueue_timer *our_timer;
201 
202  if (!(our_timer = lookup_timer(handle))) {
203  return -1;
204  }
205 
206  if (our_timer->unacked < quantity) {
207  ast_debug(1, "Acking more events than have expired?!!\n");
208  our_timer->unacked = 0;
209  ao2_ref(our_timer, -1);
210  return -1;
211  } else {
212  our_timer->unacked -= quantity;
213  }
214 
215  ao2_ref(our_timer, -1);
216  return 0;
217 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define lookup_timer(a)
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.

138 {
139  struct kqueue_timer *our_timer;
140 
141  if (!(our_timer = lookup_timer(handle))) {
142  return;
143  }
144 
145  ao2_unlink(kqueue_timers, our_timer);
146  ao2_ref(our_timer, -1);
147 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define lookup_timer(a)
static struct ao2_container * kqueue_timers
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static int kqueue_timer_cmp ( void *  obj,
void *  args,
int  flags 
)
static

Definition at line 87 of file res_timing_kqueue.c.

References args, CMP_MATCH, CMP_STOP, and kqueue_timer::handle.

Referenced by load_module().

88 {
89  struct kqueue_timer *timer1 = obj, *timer2 = args;
90  return timer1->handle == timer2->handle ? CMP_MATCH | CMP_STOP : 0;
91 }
static struct @350 args
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.

235 {
236  struct kqueue_timer *our_timer;
237 
238  if (!(our_timer = lookup_timer(handle))) {
239  return -1;
240  }
241 
242  kqueue_set_nsecs(our_timer, our_timer->nsecs);
243  our_timer->is_continuous = 0;
244  our_timer->unacked = 0;
245  ao2_ref(our_timer, -1);
246  return 0;
247 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void kqueue_set_nsecs(struct kqueue_timer *our_timer, uint64_t nsecs)
#define lookup_timer(a)
unsigned int is_continuous
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.

220 {
221  struct kqueue_timer *our_timer;
222 
223  if (!(our_timer = lookup_timer(handle))) {
224  return -1;
225  }
226 
227  kqueue_set_nsecs(our_timer, 1);
228  our_timer->is_continuous = 1;
229  our_timer->unacked = 0;
230  ao2_ref(our_timer, -1);
231  return 0;
232 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void kqueue_set_nsecs(struct kqueue_timer *our_timer, uint64_t nsecs)
#define lookup_timer(a)
unsigned int is_continuous
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.

250 {
251  enum ast_timer_event res = -1;
252  struct kqueue_timer *our_timer;
253  struct timespec sixty_seconds = { 60, 0 };
254  struct kevent kev;
255 
256  if (!(our_timer = lookup_timer(handle))) {
257  return -1;
258  }
259 
260  /* If we have non-ACKed events, just return immediately */
261  if (our_timer->unacked == 0) {
262  if (kevent(handle, NULL, 0, &kev, 1, &sixty_seconds) > 0) {
263  our_timer->unacked += kev.data;
264  }
265  }
266 
267  if (our_timer->unacked > 0) {
269  }
270 
271  ao2_ref(our_timer, -1);
272  return res;
273 }
ast_timer_event
Definition: timing.h:57
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define lookup_timer(a)
unsigned int is_continuous
static unsigned int kqueue_timer_get_max_rate ( int  handle)
static

Definition at line 275 of file res_timing_kqueue.c.

276 {
277  /* Actually, the max rate is 2^64-1 seconds, but that's not representable in a 32-bit integer. */
278  return UINT_MAX;
279 }
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().

81 {
82  const struct kqueue_timer *timer = obj;
83 
84  return timer->handle;
85 }
static struct ast_timer * timer
Definition: chan_iax2.c:313
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().

116 {
117  struct kqueue_timer *timer;
118  int handle;
119 
120  if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
121  ast_log(LOG_ERROR, "Could not allocate memory for kqueue_timer structure\n");
122  return -1;
123  }
124  if ((handle = kqueue()) < 0) {
125  ast_log(LOG_ERROR, "Failed to create kqueue timer: %s\n", strerror(errno));
126  ao2_ref(timer, -1);
127  return -1;
128  }
129 
130  timer->handle = handle;
131  ao2_link(kqueue_timers, timer);
132  /* Get rid of the reference from the allocation */
133  ao2_ref(timer, -1);
134  return handle;
135 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
static void timer_destroy(void *obj)
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
int errno
static struct ast_timer * timer
Definition: chan_iax2.c:313
static struct ao2_container * kqueue_timers
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.

185 {
186  struct kqueue_timer *our_timer;
187 
188  if (!(our_timer = lookup_timer(handle))) {
189  return -1;
190  }
191 
192  kqueue_set_nsecs(our_timer, (our_timer->nsecs = rate ? (long) (1000000000 / rate) : 0L));
193  ao2_ref(our_timer, -1);
194 
195  return 0;
196 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void kqueue_set_nsecs(struct kqueue_timer *our_timer, uint64_t nsecs)
#define lookup_timer(a)
static int load_module ( void  )
static

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

369 {
372  }
373 
375  ao2_ref(kqueue_timers, -1);
377  }
378 
379  AST_TEST_REGISTER(test_kqueue_timing);
381 }
static struct ast_timing_interface kqueue_timing
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int kqueue_timer_cmp(void *obj, void *args, int flags)
static int kqueue_timer_hash(const void *obj, const int flags)
static void * timing_funcs_handle
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition: timing.h:94
static struct ao2_container * kqueue_timers
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().

94 {
95  struct kqueue_timer *timer = obj;
96  close(timer->handle);
97 }
static struct ast_timer * timer
Definition: chan_iax2.c:313
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.

384 {
385  int res;
386 
387  AST_TEST_UNREGISTER(test_kqueue_timing);
389  ao2_ref(kqueue_timers, -1);
390  kqueue_timers = NULL;
391  }
392 
393  return res;
394 }
int ast_unregister_timing_interface(void *handle)
Unregister a previously registered timing interface.
Definition: timing.c:105
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static void * timing_funcs_handle
static struct ao2_container * kqueue_timers

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.

struct ast_timing_interface kqueue_timing
static

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