Asterisk - The Open Source Telephony Project GIT-master-f36a736
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.

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.

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}
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
@ 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 struct ast_timing_interface timerfd_timing
static void * timing_funcs_handle
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition: timing.h:95

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

◆ timer_destroy()

static void timer_destroy ( void *  obj)
static

Definition at line 76 of file res_timing_timerfd.c.

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:364

References timer.

Referenced by timerfd_timer_open().

◆ timerfd_timer_ack()

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

Definition at line 127 of file res_timing_timerfd.c.

128{
129 struct timerfd_timer *timer = data;
130 uint64_t expirations;
131 int read_result = 0;
132 int res = 0;
133
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
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:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ast_debug(level,...)
Log a DEBUG message.
int errno

References ao2_lock, ao2_unlock, ast_debug, ast_log, errno, LOG_ERROR, and timer.

◆ timerfd_timer_close()

static void timerfd_timer_close ( void *  data)
static

Definition at line 101 of file res_timing_timerfd.c.

102{
103 ao2_ref(data, -1);
104}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459

References ao2_ref.

◆ timerfd_timer_disable_continuous()

static int timerfd_timer_disable_continuous ( void *  data)
static

Definition at line 198 of file res_timing_timerfd.c.

199{
200 struct timerfd_timer *timer = data;
201 int res;
202
204
205 if (!timer->is_continuous) {
206 /* No reason to do anything if we're not
207 * in continuous mode
208 */
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));
217
218 return res;
219}
#define NULL
Definition: resample.c:96

References ao2_lock, ao2_unlock, NULL, and timer.

◆ timerfd_timer_enable_continuous()

static int timerfd_timer_enable_continuous ( void *  data)
static

Definition at line 173 of file res_timing_timerfd.c.

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
182
183 if (timer->is_continuous) {
184 /*It's already in continous mode, no need to do
185 * anything further
186 */
188 return 0;
189 }
190
191 res = timerfd_settime(timer->fd, 0, &continuous_timer, &timer->saved_timer);
192 timer->is_continuous = 1;
194
195 return res;
196}

References ao2_lock, ao2_unlock, and timer.

◆ timerfd_timer_fd()

static int timerfd_timer_fd ( void *  data)
static

Definition at line 244 of file res_timing_timerfd.c.

245{
246 struct timerfd_timer *timer = data;
247
248 return timer->fd;
249}

References timer.

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

222{
223 struct timerfd_timer *timer = data;
224 enum ast_timer_event res;
225
227
228 if (timer->is_continuous) {
230 } else {
232 }
233
235
236 return res;
237}
ast_timer_event
Definition: timing.h:57
@ AST_TIMING_EVENT_CONTINUOUS
Definition: timing.h:59
@ AST_TIMING_EVENT_EXPIRED
Definition: timing.h:58

References ao2_lock, ao2_unlock, AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, and timer.

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

240{
241 return TIMERFD_MAX_RATE;
242}
#define TIMERFD_MAX_RATE

References TIMERFD_MAX_RATE.

◆ timerfd_timer_open()

static void * timerfd_timer_open ( void  )
static

Definition at line 84 of file res_timing_timerfd.c.

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 ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void timer_destroy(void *obj)

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

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

107{
108 struct timerfd_timer *timer = data;
109 int res = 0;
110
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
123
124 return res;
125}

References ao2_lock, ao2_unlock, NULL, and timer.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 270 of file res_timing_timerfd.c.

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

References 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 = "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.

Referenced by load_module().

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