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"
Go to the source code of this file.
Data Structures | |
| struct | timerfd_timer |
Defines | |
| #define | TIMERFD_MAX_RATE 1000 |
| #define | TIMERFD_TIMER_BUCKETS 563 |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | load_module (void) |
| static void | timer_destroy (void *obj) |
| static void | timerfd_timer_ack (int handle, unsigned int quantity) |
| static void | timerfd_timer_close (int handle) |
| static int | timerfd_timer_cmp (void *obj, void *args, int flags) |
| static int | timerfd_timer_disable_continuous (int handle) |
| static int | timerfd_timer_enable_continuous (int handle) |
| static enum ast_timer_event | timerfd_timer_get_event (int handle) |
| static unsigned int | timerfd_timer_get_max_rate (int handle) |
| static int | timerfd_timer_hash (const void *obj, const int flags) |
| static int | timerfd_timer_open (void) |
| static int | timerfd_timer_set_rate (int handle, 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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .load_pri = 10, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ao2_container * | timerfd_timers |
| static struct ast_timing_interface | timerfd_timing |
| static void * | timing_funcs_handle |
timerfd timing interface
Definition in file res_timing_timerfd.c.
| #define TIMERFD_MAX_RATE 1000 |
Definition at line 68 of file res_timing_timerfd.c.
Referenced by timerfd_timer_get_max_rate().
| #define TIMERFD_TIMER_BUCKETS 563 |
Definition at line 67 of file res_timing_timerfd.c.
Referenced by load_module().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 303 of file res_timing_timerfd.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 303 of file res_timing_timerfd.c.
| static int load_module | ( | void | ) | [static] |
Definition at line 263 of file res_timing_timerfd.c.
References ao2_container_alloc, ao2_ref, ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_timing_interface, LOG_ERROR, TIMERFD_TIMER_BUCKETS, timerfd_timer_cmp(), timerfd_timer_hash(), and timing_funcs_handle.
00264 { 00265 int fd; 00266 00267 /* Make sure we support the necessary clock type */ 00268 if ((fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) { 00269 ast_log(LOG_ERROR, "CLOCK_MONOTONIC not supported. Not loading.\n"); 00270 return AST_MODULE_LOAD_DECLINE; 00271 } 00272 00273 close(fd); 00274 00275 if (!(timerfd_timers = ao2_container_alloc(TIMERFD_TIMER_BUCKETS, timerfd_timer_hash, timerfd_timer_cmp))) { 00276 return AST_MODULE_LOAD_DECLINE; 00277 } 00278 00279 if (!(timing_funcs_handle = ast_register_timing_interface(&timerfd_timing))) { 00280 ao2_ref(timerfd_timers, -1); 00281 return AST_MODULE_LOAD_DECLINE; 00282 } 00283 00284 return AST_MODULE_LOAD_SUCCESS; 00285 }
| static void timer_destroy | ( | void * | obj | ) | [static] |
Definition at line 89 of file res_timing_timerfd.c.
References timerfd_timer::handle, and timer.
Referenced by timerfd_timer_open().
00090 { 00091 struct timerfd_timer *timer = obj; 00092 close(timer->handle); 00093 }
| static void timerfd_timer_ack | ( | int | handle, | |
| unsigned int | quantity | |||
| ) | [static] |
Definition at line 158 of file res_timing_timerfd.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
00159 { 00160 uint64_t expirations; 00161 int read_result = 0; 00162 00163 do { 00164 read_result = read(handle, &expirations, sizeof(expirations)); 00165 if (read_result == -1) { 00166 if (errno == EINTR) { 00167 continue; 00168 } else { 00169 ast_log(LOG_ERROR, "Read error: %s\n", strerror(errno)); 00170 break; 00171 } 00172 } 00173 } while (read_result != sizeof(expirations)); 00174 00175 if (expirations != quantity) { 00176 ast_debug(2, "Expected to acknowledge %u ticks but got %llu instead\n", quantity, (unsigned long long) expirations); 00177 } 00178 }
| static void timerfd_timer_close | ( | int | handle | ) | [static] |
Definition at line 117 of file res_timing_timerfd.c.
References ao2_find, ao2_ref, ao2_unlink, ast_log(), LOG_ERROR, and OBJ_POINTER.
00118 { 00119 struct timerfd_timer *our_timer, find_helper = { 00120 .handle = handle, 00121 }; 00122 00123 if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) { 00124 ast_log(LOG_ERROR, "Couldn't find timer with handle %d\n", handle); 00125 return; 00126 } 00127 00128 ao2_unlink(timerfd_timers, our_timer); 00129 ao2_ref(our_timer, -1); 00130 }
| static int timerfd_timer_cmp | ( | void * | obj, | |
| void * | args, | |||
| int | flags | |||
| ) | [static] |
Definition at line 83 of file res_timing_timerfd.c.
References CMP_MATCH, CMP_STOP, and timerfd_timer::handle.
Referenced by load_module().
00084 { 00085 struct timerfd_timer *timer1 = obj, *timer2 = args; 00086 return timer1->handle == timer2->handle ? CMP_MATCH | CMP_STOP : 0; 00087 }
| static int timerfd_timer_disable_continuous | ( | int | handle | ) | [static] |
Definition at line 209 of file res_timing_timerfd.c.
References ao2_find, ao2_ref, ast_log(), timerfd_timer::is_continuous, LOG_ERROR, OBJ_POINTER, and timerfd_timer::saved_timer.
00210 { 00211 int res; 00212 struct timerfd_timer *our_timer, find_helper = { 00213 .handle = handle, 00214 }; 00215 00216 if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) { 00217 ast_log(LOG_ERROR, "Couldn't find timer with handle %d\n", handle); 00218 return -1; 00219 } 00220 00221 if(!our_timer->is_continuous) { 00222 /* No reason to do anything if we're not 00223 * in continuous mode 00224 */ 00225 ao2_ref(our_timer, -1); 00226 return 0; 00227 } 00228 00229 res = timerfd_settime(handle, 0, &our_timer->saved_timer, NULL); 00230 our_timer->is_continuous = 0; 00231 memset(&our_timer->saved_timer, 0, sizeof(our_timer->saved_timer)); 00232 ao2_ref(our_timer, -1); 00233 return res; 00234 }
| static int timerfd_timer_enable_continuous | ( | int | handle | ) | [static] |
Definition at line 180 of file res_timing_timerfd.c.
References ao2_find, ao2_ref, ast_log(), timerfd_timer::is_continuous, LOG_ERROR, OBJ_POINTER, and timerfd_timer::saved_timer.
00181 { 00182 int res; 00183 struct itimerspec continuous_timer = { 00184 .it_value.tv_nsec = 1L, 00185 }; 00186 struct timerfd_timer *our_timer, find_helper = { 00187 .handle = handle, 00188 }; 00189 00190 if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) { 00191 ast_log(LOG_ERROR, "Couldn't find timer with handle %d\n", handle); 00192 return -1; 00193 } 00194 00195 if (our_timer->is_continuous) { 00196 /*It's already in continous mode, no need to do 00197 * anything further 00198 */ 00199 ao2_ref(our_timer, -1); 00200 return 0; 00201 } 00202 00203 res = timerfd_settime(handle, 0, &continuous_timer, &our_timer->saved_timer); 00204 our_timer->is_continuous = 1; 00205 ao2_ref(our_timer, -1); 00206 return res; 00207 }
| static enum ast_timer_event timerfd_timer_get_event | ( | int | handle | ) | [static] |
Definition at line 236 of file res_timing_timerfd.c.
References ao2_find, ao2_ref, ast_log(), AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, timerfd_timer::is_continuous, LOG_ERROR, and OBJ_POINTER.
00237 { 00238 enum ast_timer_event res; 00239 struct timerfd_timer *our_timer, find_helper = { 00240 .handle = handle, 00241 }; 00242 00243 if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) { 00244 ast_log(LOG_ERROR, "Couldn't find timer with handle %d\n", handle); 00245 return -1; 00246 } 00247 00248 if (our_timer->is_continuous) { 00249 res = AST_TIMING_EVENT_CONTINUOUS; 00250 } else { 00251 res = AST_TIMING_EVENT_EXPIRED; 00252 } 00253 00254 ao2_ref(our_timer, -1); 00255 return res; 00256 }
| static unsigned int timerfd_timer_get_max_rate | ( | int | handle | ) | [static] |
Definition at line 258 of file res_timing_timerfd.c.
References TIMERFD_MAX_RATE.
00259 { 00260 return TIMERFD_MAX_RATE; 00261 }
| static int timerfd_timer_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 76 of file res_timing_timerfd.c.
References timerfd_timer::handle, and timer.
Referenced by load_module().
00077 { 00078 const struct timerfd_timer *timer = obj; 00079 00080 return timer->handle; 00081 }
| static int timerfd_timer_open | ( | void | ) | [static] |
Definition at line 95 of file res_timing_timerfd.c.
References ao2_alloc, ao2_link, ao2_ref, ast_log(), errno, timerfd_timer::handle, LOG_ERROR, timer, and timer_destroy().
00096 { 00097 struct timerfd_timer *timer; 00098 int handle; 00099 00100 if (!(timer = ao2_alloc(sizeof(*timer), timer_destroy))) { 00101 ast_log(LOG_ERROR, "Could not allocate memory for timerfd_timer structure\n"); 00102 return -1; 00103 } 00104 if ((handle = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) { 00105 ast_log(LOG_ERROR, "Failed to create timerfd timer: %s\n", strerror(errno)); 00106 ao2_ref(timer, -1); 00107 return -1; 00108 } 00109 00110 timer->handle = handle; 00111 ao2_link(timerfd_timers, timer); 00112 /* Get rid of the reference from the allocation */ 00113 ao2_ref(timer, -1); 00114 return handle; 00115 }
| static int timerfd_timer_set_rate | ( | int | handle, | |
| unsigned int | rate | |||
| ) | [static] |
Definition at line 132 of file res_timing_timerfd.c.
References ao2_find, ao2_ref, ast_log(), timerfd_timer::is_continuous, LOG_ERROR, OBJ_POINTER, and timerfd_timer::saved_timer.
00133 { 00134 struct timerfd_timer *our_timer, find_helper = { 00135 .handle = handle, 00136 }; 00137 int res = 0; 00138 00139 if (!(our_timer = ao2_find(timerfd_timers, &find_helper, OBJ_POINTER))) { 00140 ast_log(LOG_ERROR, "Couldn't find timer with handle %d\n", handle); 00141 return -1; 00142 } 00143 00144 our_timer->saved_timer.it_value.tv_sec = 0; 00145 our_timer->saved_timer.it_value.tv_nsec = rate ? (long) (1000000000 / rate) : 0L; 00146 our_timer->saved_timer.it_interval.tv_sec = our_timer->saved_timer.it_value.tv_sec; 00147 our_timer->saved_timer.it_interval.tv_nsec = our_timer->saved_timer.it_value.tv_nsec; 00148 00149 if (!our_timer->is_continuous) { 00150 res = timerfd_settime(handle, 0, &our_timer->saved_timer, NULL); 00151 } 00152 00153 ao2_ref(our_timer, -1); 00154 00155 return res; 00156 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 287 of file res_timing_timerfd.c.
References ao2_ref, ast_unregister_timing_interface(), and timing_funcs_handle.
00288 { 00289 int res; 00290 00291 if (!(res = ast_unregister_timing_interface(timing_funcs_handle))) { 00292 ao2_ref(timerfd_timers, -1); 00293 timerfd_timers = NULL; 00294 } 00295 00296 return res; 00297 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .load_pri = 10, } [static] |
Definition at line 303 of file res_timing_timerfd.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 303 of file res_timing_timerfd.c.
struct ao2_container* timerfd_timers [static] |
Definition at line 65 of file res_timing_timerfd.c.
struct ast_timing_interface timerfd_timing [static] |
Definition at line 52 of file res_timing_timerfd.c.
void* timing_funcs_handle [static] |
Definition at line 41 of file res_timing_timerfd.c.
Referenced by load_module(), and unload_module().
1.6.2