pkg: fix wrong package name, closes FS#148, reported from Andrew Pogrebennyk
[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 "mem/shm_mem.h"
42
43 #include <unistd.h>
44
45
46 /**
47  * \brief update internal counters for running new dummy timers
48  * @param timers number of dummy timer processes
49  * @return 0 on success; -1 on error
50  */
51 int register_dummy_timers(int timers)
52 {
53         if(register_procs(timers)<0)
54                 return -1;
55         cfg_register_child(timers);
56         return 0;
57 }
58
59 /**
60  * \brief Forks a separate simple sleep() periodic timer
61  * 
62  * Forks a very basic periodic timer process, that just sleep()s for 
63  * the specified interval and then calls the timer function.
64  * The new "dummy timer" process execution start immediately, the sleep()
65  * is called first (so the first call to the timer function will happen
66  * \<interval\> seconds after the call to fork_dummy_timer)
67  * @param child_id  @see fork_process()
68  * @param desc      @see fork_process()
69  * @param make_sock @see fork_process()
70  * @param f         timer function/callback
71  * @param param     parameter passed to the timer function
72  * @param interval  interval in seconds.
73  * @return pid of the new process on success, -1 on error
74  * (doesn't return anything in the child process)
75  */
76 int fork_dummy_timer(int child_id, char* desc, int make_sock,
77                                                 timer_function* f, void* param, int interval)
78 {
79         int pid;
80         
81         pid=fork_process(child_id, desc, make_sock);
82         if (pid<0) return -1;
83         if (pid==0){
84                 /* child */
85                 if (cfg_child_init()) return -1;
86                 for(;;){
87                         sleep(interval);
88                         cfg_update();
89                         f(get_ticks(), param); /* ticks in s for compatibility with old
90                                                                           timers */
91                 }
92         }
93         /* parent */
94         return pid;
95 }
96
97
98
99 /**
100  * \brief Forks a timer process based on the local timer
101  * 
102  * Forks a separate timer process running a local_timer.h type of timer
103  * A pointer to the local_timer handle (allocated in shared memory) is
104  * returned in lt_h. It can be used to add/delete more timers at runtime
105  * (via local_timer_add()/local_timer_del() a.s.o).
106  * If timers are added from separate processes, some form of locking must be
107  * used (all the calls to local_timer* must be enclosed by locks if it
108  * cannot be guaranteed that they cannot execute in the same time)
109  * The timer "engine" must be run manually from the child process. For
110  * example a very simple local timer process that just runs a single 
111  * periodic timer can be started in the following way:
112  * struct local_timer* lt_h;
113  * 
114  * pid=fork_local_timer_process(...., &lt_h);
115  * if (pid==0){
116  *          timer_init(&my_timer, my_timer_f, 0, 0);
117  *          local_timer_add(&lt_h, &my_timer, S_TO_TICKS(10), get_ticks_raw());
118  *          while(1) { sleep(1); local_timer_run(lt, get_ticks_raw()); }
119  * }
120  *
121  * @param child_id  @see fork_process()
122  * @param desc      @see fork_process()
123  * @param make_sock @see fork_process()
124  * @param lt_h      local_timer handler
125  * @return pid to the parent, 0 to the child, -1 if error.
126  */
127 int fork_local_timer_process(int child_id, char* desc, int make_sock,
128                                                 struct local_timer** lt_h)
129 {
130         int pid;
131         struct local_timer* lt;
132         
133         lt=shm_malloc(sizeof(*lt));
134         if (lt==0) goto error;
135         if (init_local_timer(lt, get_ticks_raw())<0) goto error;
136         pid=fork_process(child_id, desc, make_sock);
137         if (pid<0) goto error;
138         *lt_h=lt;
139         return pid;
140 error:
141         if (lt) shm_free(lt);
142         return -1;
143 }
144
145
146 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */