kamailio.cfg: removed sample db_mode parameter for domain module
[sip-router] / timer_proc.c
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2009 iptelorg GmbH
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * timer_proc.c  - separate process timers
20  * (unrelated to the main fast and slow timers)
21  */
22 /*
23  * History:
24  * --------
25  *  2009-03-10  initial version (andrei)
26 */
27
28 /**
29  * @file
30  * @brief SIP-router core ::  timer - separate process timers
31  *
32  *  (unrelated to the main fast and slow timers)
33  *
34  * @ingroup core
35  * Module: @ref core
36  */
37
38 #include "timer_proc.h"
39 #include "cfg/cfg_struct.h"
40 #include "pt.h"
41 #include "ut.h"
42 #include "mem/shm_mem.h"
43
44 #include <unistd.h>
45
46
47 /**
48  * \brief update internal counters for running new basic sec. timers
49  * @param timers number of basic timer processes
50  * @return 0 on success; -1 on error
51  */
52 int register_basic_timers(int timers)
53 {
54         if(register_procs(timers)<0)
55                 return -1;
56         cfg_register_child(timers);
57         return 0;
58 }
59
60 /**
61  * \brief Forks a separate simple sleep() periodic timer
62  * 
63  * Forks a very basic periodic timer process, that just sleep()s for 
64  * the specified interval and then calls the timer function.
65  * The new "basic timer" process execution start immediately, the sleep()
66  * is called first (so the first call to the timer function will happen
67  * \<interval\> seconds after the call to fork_basic_timer)
68  * @param child_id  @see fork_process()
69  * @param desc      @see fork_process()
70  * @param make_sock @see fork_process()
71  * @param f         timer function/callback
72  * @param param     parameter passed to the timer function
73  * @param interval  interval in seconds.
74  * @return pid of the new process on success, -1 on error
75  * (doesn't return anything in the child process)
76  */
77 int fork_basic_timer(int child_id, char* desc, int make_sock,
78                                                 timer_function* f, void* param, int interval)
79 {
80         int pid;
81         
82         pid=fork_process(child_id, desc, make_sock);
83         if (pid<0) return -1;
84         if (pid==0){
85                 /* child */
86                 if (cfg_child_init()) return -1;
87                 for(;;){
88                         sleep(interval);
89                         cfg_update();
90                         f(get_ticks(), param); /* ticks in s for compatibility with old
91                                                                           timers */
92                 }
93         }
94         /* parent */
95         return pid;
96 }
97
98 /**
99  * \brief Forks a separate simple milisecond-sleep() periodic timer
100  * 
101  * Forks a very basic periodic timer process, that just ms-sleep()s for 
102  * the specified interval and then calls the timer function.
103  * The new "basic timer" process execution start immediately, the ms-sleep()
104  * is called first (so the first call to the timer function will happen
105  * \<interval\> seconds after the call to fork_basic_utimer)
106  * @param child_id  @see fork_process()
107  * @param desc      @see fork_process()
108  * @param make_sock @see fork_process()
109  * @param f         timer function/callback
110  * @param param     parameter passed to the timer function
111  * @param uinterval  interval in mili-seconds.
112  * @return pid of the new process on success, -1 on error
113  * (doesn't return anything in the child process)
114  */
115 int fork_basic_utimer(int child_id, char* desc, int make_sock,
116                                                 utimer_function* f, void* param, int uinterval)
117 {
118         int pid;
119         ticks_t ts;
120         
121         pid=fork_process(child_id, desc, make_sock);
122         if (pid<0) return -1;
123         if (pid==0){
124                 /* child */
125                 if (cfg_child_init()) return -1;
126                 for(;;){
127                         sleep_us(uinterval);
128                         cfg_update();
129                         ts = get_ticks_raw();
130                         f(TICKS_TO_MS(ts), param); /* ticks in mili-seconds */
131                 }
132         }
133         /* parent */
134         return pid;
135 }
136
137
138 /**
139  * \brief Forks a timer process based on the local timer
140  * 
141  * Forks a separate timer process running a local_timer.h type of timer
142  * A pointer to the local_timer handle (allocated in shared memory) is
143  * returned in lt_h. It can be used to add/delete more timers at runtime
144  * (via local_timer_add()/local_timer_del() a.s.o).
145  * If timers are added from separate processes, some form of locking must be
146  * used (all the calls to local_timer* must be enclosed by locks if it
147  * cannot be guaranteed that they cannot execute in the same time)
148  * The timer "engine" must be run manually from the child process. For
149  * example a very simple local timer process that just runs a single 
150  * periodic timer can be started in the following way:
151  * struct local_timer* lt_h;
152  * 
153  * pid=fork_local_timer_process(...., &lt_h);
154  * if (pid==0){
155  *          timer_init(&my_timer, my_timer_f, 0, 0);
156  *          local_timer_add(&lt_h, &my_timer, S_TO_TICKS(10), get_ticks_raw());
157  *          while(1) { sleep(1); local_timer_run(lt, get_ticks_raw()); }
158  * }
159  *
160  * @param child_id  @see fork_process()
161  * @param desc      @see fork_process()
162  * @param make_sock @see fork_process()
163  * @param lt_h      local_timer handler
164  * @return pid to the parent, 0 to the child, -1 if error.
165  */
166 int fork_local_timer_process(int child_id, char* desc, int make_sock,
167                                                 struct local_timer** lt_h)
168 {
169         int pid;
170         struct local_timer* lt;
171         
172         lt=shm_malloc(sizeof(*lt));
173         if (lt==0) goto error;
174         if (init_local_timer(lt, get_ticks_raw())<0) goto error;
175         pid=fork_process(child_id, desc, make_sock);
176         if (pid<0) goto error;
177         *lt_h=lt;
178         return pid;
179 error:
180         if (lt) shm_free(lt);
181         return -1;
182 }
183
184 /**
185  * \brief update internal counters for running new sync sec. timers
186  * @param timers number of basic timer processes
187  * @return 0 on success; -1 on error
188  */
189 int register_sync_timers(int timers)
190 {
191         if(register_procs(timers)<0)
192                 return -1;
193         cfg_register_child(timers);
194         return 0;
195 }
196
197 /**
198  * \brief Forks a separate simple sleep() -&- sync periodic timer
199  *
200  * Forks a very basic periodic timer process, that just sleep()s for 
201  * the specified interval and then calls the timer function.
202  * The new "sync timer" process execution start immediately, the sleep()
203  * is called first (so the first call to the timer function will happen
204  * \<interval\> seconds after the call to fork_sync_timer)
205  * @param child_id  @see fork_process()
206  * @param desc      @see fork_process()
207  * @param make_sock @see fork_process()
208  * @param f         timer function/callback
209  * @param param     parameter passed to the timer function
210  * @param interval  interval in seconds.
211  * @return pid of the new process on success, -1 on error
212  * (doesn't return anything in the child process)
213  */
214 int fork_sync_timer(int child_id, char* desc, int make_sock,
215                                                 timer_function* f, void* param, int interval)
216 {
217         int pid;
218         ticks_t ts1 = 0;
219         ticks_t ts2 = 0;
220
221         pid=fork_process(child_id, desc, make_sock);
222         if (pid<0) return -1;
223         if (pid==0){
224                 /* child */
225                 ts2 = interval;
226                 if (cfg_child_init()) return -1;
227                 for(;;){
228                         if(ts2>0) sleep(ts2);
229                         else sleep(1);
230                         ts1 = get_ticks();
231                         cfg_update();
232                         f(get_ticks(), param); /* ticks in s for compatibility with old
233                                                                           timers */
234                         ts2 = interval - get_ticks() + ts1;
235                 }
236         }
237         /* parent */
238         return pid;
239 }
240
241
242 /**
243  * \brief Forks a separate simple milisecond-sleep() -&- sync periodic timer
244  *
245  * Forks a very basic periodic timer process, that just ms-sleep()s for 
246  * the specified interval and then calls the timer function.
247  * The new "sync timer" process execution start immediately, the ms-sleep()
248  * is called first (so the first call to the timer function will happen
249  * \<interval\> seconds after the call to fork_basic_utimer)
250  * @param child_id  @see fork_process()
251  * @param desc      @see fork_process()
252  * @param make_sock @see fork_process()
253  * @param f         timer function/callback
254  * @param param     parameter passed to the timer function
255  * @param uinterval  interval in mili-seconds.
256  * @return pid of the new process on success, -1 on error
257  * (doesn't return anything in the child process)
258  */
259 int fork_sync_utimer(int child_id, char* desc, int make_sock,
260                                                 utimer_function* f, void* param, int uinterval)
261 {
262         int pid;
263         ticks_t ts1 = 0;
264         ticks_t ts2 = 0;
265
266         pid=fork_process(child_id, desc, make_sock);
267         if (pid<0) return -1;
268         if (pid==0){
269                 /* child */
270                 ts2 = uinterval;
271                 if (cfg_child_init()) return -1;
272                 for(;;){
273                         if(ts2>0) sleep_us(uinterval);
274                         else sleep_us(1);
275                         ts1 = get_ticks_raw();
276                         cfg_update();
277                         f(TICKS_TO_MS(ts1), param); /* ticks in mili-seconds */
278                         ts2 = uinterval - get_ticks_raw() + ts1;
279                 }
280         }
281         /* parent */
282         return pid;
283 }
284
285
286 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */