a1801fa68c2f10813769f6c1f95b08e86ff09a35
[asterisk/asterisk.git] / main / timing.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Digium, Inc.
5  *
6  * Kevin P. Fleming <kpfleming@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Timing source management
22  *
23  * \author Kevin P. Fleming <kpfleming@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/timing.h"
31 #include "asterisk/lock.h"
32
33 AST_RWLOCK_DEFINE_STATIC(lock);
34
35 static struct ast_timing_functions timer_funcs;
36
37 void *ast_install_timing_functions(struct ast_timing_functions *funcs)
38 {
39         if (!funcs->timer_open ||
40             !funcs->timer_close ||
41                 !funcs->timer_set_rate ||
42             !funcs->timer_ack ||
43             !funcs->timer_get_event ||
44             !funcs->timer_enable_continuous ||
45             !funcs->timer_disable_continuous) {
46                 return NULL;
47         }
48
49         ast_rwlock_wrlock(&lock);
50
51         if (timer_funcs.timer_open) {
52                 ast_rwlock_unlock(&lock);
53                 ast_log(LOG_NOTICE, "Multiple timing modules are loaded.  You should only load one.\n");
54                 return NULL;
55         }
56         
57         timer_funcs = *funcs;
58
59         ast_rwlock_unlock(&lock);
60
61         return &timer_funcs;
62 }
63
64 void ast_uninstall_timing_functions(void *handle)
65 {
66         ast_rwlock_wrlock(&lock);
67
68         if (handle != &timer_funcs) {
69                 ast_rwlock_unlock(&lock);
70                 return;
71         }
72
73         memset(&timer_funcs, 0, sizeof(timer_funcs));
74
75         ast_rwlock_unlock(&lock);
76 }
77
78 int ast_timer_open(void)
79 {
80         int timer;
81
82         ast_rwlock_rdlock(&lock);
83
84         if (!timer_funcs.timer_open) {
85                 ast_rwlock_unlock(&lock);
86                 return -1;
87         }
88
89         timer = timer_funcs.timer_open();
90
91         ast_rwlock_unlock(&lock);
92
93         return timer;
94 }
95
96 void ast_timer_close(int timer)
97 {
98         ast_rwlock_rdlock(&lock);
99
100         if (!timer_funcs.timer_close) {
101                 ast_rwlock_unlock(&lock);
102                 return;
103         }
104
105         timer_funcs.timer_close(timer);
106
107         ast_rwlock_unlock(&lock);
108 }
109
110 int ast_timer_set_rate(int handle, unsigned int rate)
111 {
112         int res;
113
114         ast_rwlock_rdlock(&lock);
115
116         if (!timer_funcs.timer_set_rate) {
117                 ast_rwlock_unlock(&lock);
118                 return -1;
119         }
120
121         res = timer_funcs.timer_set_rate(handle, rate);
122
123         ast_rwlock_unlock(&lock);
124
125         return res;
126 }
127
128 void ast_timer_ack(int handle, unsigned int quantity)
129 {
130         ast_rwlock_rdlock(&lock);
131
132         if (!timer_funcs.timer_ack) {
133                 ast_rwlock_unlock(&lock);
134                 return;
135         }
136
137         timer_funcs.timer_ack(handle, quantity);
138
139         ast_rwlock_unlock(&lock);
140 }
141
142 int ast_timer_enable_continuous(int handle)
143 {
144         int result;
145
146         ast_rwlock_rdlock(&lock);
147
148         if (!timer_funcs.timer_enable_continuous) {
149                 ast_rwlock_unlock(&lock);
150                 return -1;
151         }
152
153         result = timer_funcs.timer_enable_continuous(handle);
154
155         ast_rwlock_unlock(&lock);
156
157         return result;
158 }
159
160 int ast_timer_disable_continuous(int handle)
161 {
162         int result;
163
164         ast_rwlock_rdlock(&lock);
165
166         if (!timer_funcs.timer_disable_continuous) {
167                 ast_rwlock_unlock(&lock);
168                 return -1;
169         }
170
171         result = timer_funcs.timer_disable_continuous(handle);
172
173         ast_rwlock_unlock(&lock);
174
175         return result;
176 }
177
178 enum ast_timing_event ast_timer_get_event(int handle)
179 {
180         enum ast_timing_event result;
181
182         ast_rwlock_rdlock(&lock);
183
184         if (!timer_funcs.timer_get_event) {
185                 ast_rwlock_unlock(&lock);
186                 return -1;
187         }
188
189         result = timer_funcs.timer_get_event(handle);
190
191         ast_rwlock_unlock(&lock);
192
193         return result;
194 }