add infrastructure so that timing source can be a loadable module... next steps are...
[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_MUTEX_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_ack ||
42             !funcs->timer_get_event ||
43             !funcs->timer_enable_continuous ||
44             !funcs->timer_disable_continuous) {
45                 return NULL;
46         }
47
48         ast_mutex_lock(&lock);
49
50         if (timer_funcs.timer_open) {
51                 ast_mutex_unlock(&lock);
52                 return NULL;
53         }
54         
55         timer_funcs = *funcs;
56
57         ast_mutex_unlock(&lock);
58
59         return &timer_funcs;
60 }
61
62 void ast_uninstall_timing_functions(void *handle)
63 {
64         ast_mutex_lock(&lock);
65
66         if (handle != &timer_funcs) {
67                 ast_mutex_unlock(&lock);
68                 return;
69         }
70
71         memset(&timer_funcs, 0, sizeof(timer_funcs));
72
73         ast_mutex_unlock(&lock);
74 }
75
76 int ast_timer_open(unsigned int rate)
77 {
78         int timer;
79
80         ast_mutex_lock(&lock);
81
82         if (!timer_funcs.timer_open) {
83                 ast_mutex_unlock(&lock);
84                 return -1;
85         }
86
87         timer = timer_funcs.timer_open(rate);
88
89         ast_mutex_unlock(&lock);
90
91         return timer;
92 }
93
94 void ast_timer_close(int timer)
95 {
96         ast_mutex_lock(&lock);
97
98         if (!timer_funcs.timer_close) {
99                 ast_mutex_unlock(&lock);
100                 return;
101         }
102
103         timer_funcs.timer_close(timer);
104
105         ast_mutex_unlock(&lock);
106 }
107
108 void ast_timer_ack(int handle, unsigned int quantity)
109 {
110         ast_mutex_lock(&lock);
111
112         if (!timer_funcs.timer_ack) {
113                 ast_mutex_unlock(&lock);
114                 return;
115         }
116
117         timer_funcs.timer_ack(handle, quantity);
118
119         ast_mutex_unlock(&lock);
120 }
121
122 int ast_timer_enable_continuous(int handle)
123 {
124         int result;
125
126         ast_mutex_lock(&lock);
127
128         if (!timer_funcs.timer_enable_continuous) {
129                 ast_mutex_unlock(&lock);
130                 return -1;
131         }
132
133         result = timer_funcs.timer_enable_continuous(handle);
134
135         ast_mutex_unlock(&lock);
136
137         return result;
138 }
139
140 int ast_timer_disable_continous(int handle)
141 {
142         int result;
143
144         ast_mutex_lock(&lock);
145
146         if (!timer_funcs.timer_disable_continuous) {
147                 ast_mutex_unlock(&lock);
148                 return -1;
149         }
150
151         result = timer_funcs.timer_disable_continuous(handle);
152
153         ast_mutex_unlock(&lock);
154
155         return result;
156 }
157
158 enum ast_timing_event ast_timer_get_event(int handle)
159 {
160         enum ast_timing_event result;
161
162         ast_mutex_lock(&lock);
163
164         if (!timer_funcs.timer_get_event) {
165                 ast_mutex_unlock(&lock);
166                 return -1;
167         }
168
169         result = timer_funcs.timer_get_event(handle);
170
171         ast_mutex_unlock(&lock);
172
173         return result;
174 }