Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
res_timing_timerfd.c File Reference

timerfd timing interface More...

#include "asterisk.h"
#include <sys/timerfd.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 dependency graph for res_timing_timerfd.c:

Go to the source code of this file.

Data Structures

struct  timerfd_timer
 

Macros

#define TIMERFD_MAX_RATE   1000
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void timer_destroy (void *obj)
 
static int timerfd_timer_ack (void *data, unsigned int quantity)
 
static void timerfd_timer_close (void *data)
 
static int timerfd_timer_disable_continuous (void *data)
 
static int timerfd_timer_enable_continuous (void *data)
 
static int timerfd_timer_fd (void *data)
 
static enum ast_timer_event timerfd_timer_get_event (void *data)
 
static unsigned int timerfd_timer_get_max_rate (void *data)
 
static void * timerfd_timer_open (void)
 
static int timerfd_timer_set_rate (void *data, unsigned int rate)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Timerfd 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_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_TIMING, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_timing_interface timerfd_timing
 
static void * timing_funcs_handle
 

Detailed Description

timerfd timing interface

Author
Mark Michelson mmich.nosp@m.elso.nosp@m.n@dig.nosp@m.ium..nosp@m.com

Definition in file res_timing_timerfd.c.

Macro Definition Documentation

◆ TIMERFD_MAX_RATE

#define TIMERFD_MAX_RATE   1000

Definition at line 68 of file res_timing_timerfd.c.

Referenced by timerfd_timer_get_max_rate().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 280 of file res_timing_timerfd.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 280 of file res_timing_timerfd.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 280 of file res_timing_timerfd.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 251 of file res_timing_timerfd.c.

References ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_timing_interface, timerfd_timer::fd, LOG_ERROR, and timing_funcs_handle.

Referenced by unload_module().

252 {
253  int fd;
254 
255  /* Make sure we support the necessary clock type */
256  if ((fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) {
257  ast_log(LOG_ERROR, "timerfd_create() not supported by the kernel. Not loading.\n");
259  }
260 
261  close(fd);
262 
265  }
266 
268 }
static void * timing_funcs_handle
static struct ast_timing_interface timerfd_timing
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition: timing.h:95

◆ timer_destroy()

static void timer_destroy ( void *  obj)
static

Definition at line 76 of file res_timing_timerfd.c.

References timerfd_timer::fd, and timer.

Referenced by timerfd_timer_open().

77 {
78  struct timerfd_timer *timer = obj;
79  if (timer->fd > -1) {
80  close(timer->fd);
81  }
82 }
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_ack()

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

Definition at line 127 of file res_timing_timerfd.c.

References ao2_lock, ao2_unlock, ast_debug, ast_log, errno, timerfd_timer::fd, LOG_ERROR, and timer.

128 {
129  struct timerfd_timer *timer = data;
130  uint64_t expirations;
131  int read_result = 0;
132  int res = 0;
133 
134  ao2_lock(timer);
135 
136  do {
137  struct itimerspec timer_status;
138 
139  if (timerfd_gettime(timer->fd, &timer_status)) {
140  ast_log(LOG_ERROR, "Call to timerfd_gettime() using handle %d error: %s\n", timer->fd, strerror(errno));
141  expirations = 0;
142  res = -1;
143  break;
144  }
145 
146  if (timer_status.it_value.tv_sec == 0 && timer_status.it_value.tv_nsec == 0) {
147  ast_debug(1, "Avoiding read on disarmed timerfd %d\n", timer->fd);
148  expirations = 0;
149  break;
150  }
151 
152  read_result = read(timer->fd, &expirations, sizeof(expirations));
153  if (read_result == -1) {
154  if (errno == EINTR || errno == EAGAIN) {
155  continue;
156  } else {
157  ast_log(LOG_ERROR, "Read error: %s\n", strerror(errno));
158  res = -1;
159  break;
160  }
161  }
162  } while (read_result != sizeof(expirations));
163 
164  ao2_unlock(timer);
165 
166  if (expirations != quantity) {
167  ast_debug(2, "Expected to acknowledge %u ticks but got %llu instead\n", quantity, (unsigned long long) expirations);
168  }
169 
170  return res;
171 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
int errno
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_close()

static void timerfd_timer_close ( void *  data)
static

Definition at line 101 of file res_timing_timerfd.c.

References ao2_ref.

102 {
103  ao2_ref(data, -1);
104 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ timerfd_timer_disable_continuous()

static int timerfd_timer_disable_continuous ( void *  data)
static

Definition at line 198 of file res_timing_timerfd.c.

References ao2_lock, ao2_unlock, timerfd_timer::fd, timerfd_timer::is_continuous, NULL, timerfd_timer::saved_timer, and timer.

199 {
200  struct timerfd_timer *timer = data;
201  int res;
202 
203  ao2_lock(timer);
204 
205  if (!timer->is_continuous) {
206  /* No reason to do anything if we're not
207  * in continuous mode
208  */
209  ao2_unlock(timer);
210  return 0;
211  }
212 
213  res = timerfd_settime(timer->fd, 0, &timer->saved_timer, NULL);
214  timer->is_continuous = 0;
215  memset(&timer->saved_timer, 0, sizeof(timer->saved_timer));
216  ao2_unlock(timer);
217 
218  return res;
219 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
unsigned int is_continuous
struct itimerspec saved_timer
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_enable_continuous()

static int timerfd_timer_enable_continuous ( void *  data)
static

Definition at line 173 of file res_timing_timerfd.c.

References ao2_lock, ao2_unlock, timerfd_timer::fd, timerfd_timer::is_continuous, timerfd_timer::saved_timer, and timer.

174 {
175  struct timerfd_timer *timer = data;
176  int res;
177  static const struct itimerspec continuous_timer = {
178  .it_value.tv_nsec = 1L,
179  };
180 
181  ao2_lock(timer);
182 
183  if (timer->is_continuous) {
184  /*It's already in continous mode, no need to do
185  * anything further
186  */
187  ao2_unlock(timer);
188  return 0;
189  }
190 
191  res = timerfd_settime(timer->fd, 0, &continuous_timer, &timer->saved_timer);
192  timer->is_continuous = 1;
193  ao2_unlock(timer);
194 
195  return res;
196 }
#define ao2_unlock(a)
Definition: astobj2.h:730
unsigned int is_continuous
struct itimerspec saved_timer
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_fd()

static int timerfd_timer_fd ( void *  data)
static

Definition at line 244 of file res_timing_timerfd.c.

References timerfd_timer::fd, and timer.

245 {
246  struct timerfd_timer *timer = data;
247 
248  return timer->fd;
249 }
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_get_event()

static enum ast_timer_event timerfd_timer_get_event ( void *  data)
static

Definition at line 221 of file res_timing_timerfd.c.

References ao2_lock, ao2_unlock, AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, timerfd_timer::is_continuous, and timer.

222 {
223  struct timerfd_timer *timer = data;
224  enum ast_timer_event res;
225 
226  ao2_lock(timer);
227 
228  if (timer->is_continuous) {
230  } else {
232  }
233 
234  ao2_unlock(timer);
235 
236  return res;
237 }
ast_timer_event
Definition: timing.h:57
#define ao2_unlock(a)
Definition: astobj2.h:730
unsigned int is_continuous
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_get_max_rate()

static unsigned int timerfd_timer_get_max_rate ( void *  data)
static

Definition at line 239 of file res_timing_timerfd.c.

References TIMERFD_MAX_RATE.

240 {
241  return TIMERFD_MAX_RATE;
242 }
#define TIMERFD_MAX_RATE

◆ timerfd_timer_open()

static void * timerfd_timer_open ( void  )
static

Definition at line 84 of file res_timing_timerfd.c.

References ao2_alloc, ao2_ref, ast_log, errno, timerfd_timer::fd, LOG_ERROR, NULL, timer, and timer_destroy().

85 {
86  struct timerfd_timer *timer;
87 
88  if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) {
89  ast_log(LOG_ERROR, "Could not allocate memory for timerfd_timer structure\n");
90  return NULL;
91  }
92  if ((timer->fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) {
93  ast_log(LOG_ERROR, "Failed to create timerfd timer: %s\n", strerror(errno));
94  ao2_ref(timer, -1);
95  return NULL;
96  }
97 
98  return timer;
99 }
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void timer_destroy(void *obj)
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ timerfd_timer_set_rate()

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

Definition at line 106 of file res_timing_timerfd.c.

References ao2_lock, ao2_unlock, timerfd_timer::fd, timerfd_timer::is_continuous, NULL, timerfd_timer::saved_timer, and timer.

107 {
108  struct timerfd_timer *timer = data;
109  int res = 0;
110 
111  ao2_lock(timer);
112 
113  timer->saved_timer.it_value.tv_sec = 0;
114  timer->saved_timer.it_value.tv_nsec = rate ? (long) (1000000000 / rate) : 0L;
115  timer->saved_timer.it_interval.tv_sec = timer->saved_timer.it_value.tv_sec;
116  timer->saved_timer.it_interval.tv_nsec = timer->saved_timer.it_value.tv_nsec;
117 
118  if (!timer->is_continuous) {
119  res = timerfd_settime(timer->fd, 0, &timer->saved_timer, NULL);
120  }
121 
122  ao2_unlock(timer);
123 
124  return res;
125 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
unsigned int is_continuous
struct itimerspec saved_timer
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 270 of file res_timing_timerfd.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_TIMING, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_unregister_timing_interface(), ASTERISK_GPL_KEY, load_module(), and timing_funcs_handle.

271 {
273 }
int ast_unregister_timing_interface(void *handle)
Unregister a previously registered timing interface.
Definition: timing.c:104
static void * timing_funcs_handle

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Timerfd 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_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_TIMING, }
static

Definition at line 280 of file res_timing_timerfd.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 280 of file res_timing_timerfd.c.

◆ timerfd_timing

struct ast_timing_interface timerfd_timing
static

Definition at line 54 of file res_timing_timerfd.c.

◆ timing_funcs_handle

void* timing_funcs_handle
static

Definition at line 42 of file res_timing_timerfd.c.

Referenced by load_module(), and unload_module().