Browse code

- added missing pt.c

Andrei Pelinescu-Onciul authored on 20/09/2006 09:01:48
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,272 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Process Table
4
+ *
5
+ *
6
+ *
7
+ * Copyright (C) 2001-2003 FhG Fokus
8
+ *
9
+ * This file is part of ser, a free SIP server.
10
+ *
11
+ * ser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * For a license to use the ser software under conditions
17
+ * other than those described here, or to purchase support for this
18
+ * software, please contact iptel.org by e-mail at the following addresses:
19
+ *    info@iptel.org
20
+ *
21
+ * ser is distributed in the hope that it will be useful,
22
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
+ * GNU General Public License for more details.
25
+ *
26
+ * You should have received a copy of the GNU General Public License 
27
+ * along with this program; if not, write to the Free Software 
28
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
+ */
30
+/*
31
+ * History:
32
+ * --------
33
+ *  2006-06-14	added process table in shared mem (dragos)
34
+ */
35
+
36
+
37
+#include "pt.h"
38
+#include "tcp_init.h"
39
+#include "sr_module.h"
40
+
41
+#include "stdio.h"
42
+
43
+
44
+static int estimated_proc_no=0;
45
+
46
+/* returns 0 on success, -1 on error */
47
+int init_pt(int proc_no)
48
+{
49
+	estimated_proc_no+=proc_no;
50
+	/*alloc pids*/
51
+#ifdef SHM_MEM
52
+	pt=shm_malloc(sizeof(struct process_table)*estimated_proc_no);
53
+	process_count = shm_malloc(sizeof(int));
54
+#else
55
+	pt=pkg_malloc(sizeof(struct process_table)*estimated_proc_no);
56
+	process_count = pkg_malloc(sizeof(int));
57
+#endif
58
+	process_lock = lock_alloc();
59
+	process_lock = lock_init(process_lock);
60
+	if (pt==0||process_count==0||process_lock==0){
61
+		LOG(L_ERR, "ERROR: out  of memory\n");
62
+		return -1;
63
+	}
64
+	memset(pt, 0, sizeof(struct process_table)*estimated_proc_no);
65
+
66
+	process_no=0; /*main process number*/
67
+	pt[process_no].pid=getpid();
68
+	memcpy(pt[*process_count].desc,"main",5);
69
+	*process_count=1;
70
+	return 0;
71
+}
72
+
73
+
74
+/* register no processes, used from mod_init when processes will be forked
75
+ *  from mod_child 
76
+ *  returns 0 on success, -1 on error
77
+ */
78
+int register_procs(int no)
79
+{
80
+	if (pt){
81
+		LOG(L_CRIT, "BUG: register_procs(%d) called at runtime\n", no);
82
+		return -1;
83
+	}
84
+	estimated_proc_no+=no;
85
+	return 0;
86
+}
87
+
88
+
89
+
90
+/* returns the maximum number of processes */
91
+int get_max_procs()
92
+{
93
+	return estimated_proc_no;
94
+}
95
+
96
+
97
+/* return processes pid */
98
+inline int my_pid()
99
+{
100
+	return pt ? pt[process_no].pid : getpid();
101
+}
102
+
103
+/**
104
+ * Forks a new process.
105
+ * @param child_id - rank, if equal to PROC_NOCHLDINIT init_child will not be
106
+ *                   called for the new forked process (see sr_module.h)
107
+ * @param desc - text description for the process table
108
+ * @param make_sock - if to create a unix socket pair for it
109
+ * @returns the pid of the new process
110
+ */
111
+inline int fork_process(int child_id, char *desc, int make_sock)
112
+{
113
+	int pid,old_process_no;
114
+#ifdef USE_TCP
115
+	int sockfd[2];
116
+#endif
117
+
118
+	lock_get(process_lock);	
119
+	if (*process_count>=estimated_proc_no) {
120
+		LOG(L_CRIT, "ERROR: fork_process(): Process limit of %d exceeded."
121
+					" Will simulate fork fail.\n", estimated_proc_no);
122
+		lock_release(process_lock);
123
+		return -1;
124
+	}	
125
+	
126
+	#ifdef USE_TCP
127
+		if(make_sock && !tcp_disable){
128
+			 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
129
+				LOG(L_ERR, "ERROR: fork_process(): socketpair failed: %s\n",
130
+					strerror(errno));
131
+				return -1;
132
+			}
133
+		}
134
+	#endif
135
+	
136
+	old_process_no = process_no;
137
+	process_no = *process_count;
138
+	pid = fork();
139
+	if (pid<0) {
140
+		lock_release(process_lock);
141
+		return pid;
142
+	}
143
+	if (pid==0){
144
+		/* child */
145
+		/* wait for parent to get out of critical zone.
146
+		 * this is actually relevant as the parent updates
147
+		 * the pt & process_count. */
148
+		lock_get(process_lock);
149
+		#ifdef USE_TCP
150
+			if (make_sock && !tcp_disable){
151
+				close(sockfd[0]);
152
+				unix_tcp_sock=sockfd[1];
153
+			}
154
+		#endif		
155
+		lock_release(process_lock);	
156
+		if ((child_id!=PROC_NOCHLDINIT) && (init_child(child_id) < 0)) {
157
+			LOG(L_ERR, "ERROR: fork_process(): init_child failed for %s\n",
158
+						pt[process_no].desc);
159
+			return -1;
160
+		}
161
+		return pid;
162
+	} else {
163
+		/* parent */
164
+		process_no = old_process_no;
165
+		/* add the process to the list in shm */
166
+		pt[*process_count].pid=pid;
167
+		if (desc){
168
+			strncpy(pt[*process_count].desc, desc, MAX_PT_DESC);
169
+		}
170
+		#ifdef USE_TCP
171
+			if (make_sock && !tcp_disable){
172
+				close(sockfd[1]);
173
+				pt[*process_count].unix_sock=sockfd[0];
174
+				pt[*process_count].idx=-1; /* this is not "tcp" process*/
175
+			}
176
+		#endif		
177
+		*process_count = (*process_count) +1;
178
+		lock_release(process_lock);
179
+		return pid;
180
+	}
181
+}
182
+
183
+/**
184
+ * Forks a new TCP process.
185
+ * @param desc - text description for the process table
186
+ * @param r - index in the tcp_children array
187
+ * @param *reader_fd_1 - pointer to return the reader_fd[1]
188
+ * @returns the pid of the new process
189
+ */
190
+inline int fork_tcp_process(int child_id,char *desc,int r,int *reader_fd_1)
191
+{
192
+	int pid,old_process_no;
193
+	int sockfd[2];
194
+	int reader_fd[2]; /* for comm. with the tcp children read  */
195
+
196
+
197
+	
198
+	lock_get(process_lock);
199
+	/* set the local process_no */
200
+	if (*process_count>=estimated_proc_no) {
201
+		LOG(L_CRIT, "ERROR: fork_tcp_process(): Process limit of %d exceeded."
202
+					" Simulating fork fail\n", estimated_proc_no);
203
+		return -1;
204
+	}	
205
+	
206
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
207
+		LOG(L_ERR, "ERROR: fork_tcp_process(): socketpair failed: %s\n",
208
+					strerror(errno));
209
+		return -1;
210
+	}
211
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
212
+		LOG(L_ERR, "ERROR: fork_tcp_process(): socketpair failed: %s\n",
213
+					strerror(errno));
214
+		return -1;
215
+	}
216
+	if (tcp_fix_child_sockets(reader_fd)<0){
217
+		LOG(L_ERR, "ERROR: fork_tcp_process(): failed to set non blocking"
218
+					"on child sockets\n");
219
+		/* continue, it's not critical (it will go slower under
220
+		 * very high connection rates) */
221
+	}
222
+	
223
+	old_process_no = process_no;
224
+	process_no = *process_count;
225
+	pid = fork();
226
+	if (pid<0) {
227
+		lock_release(process_lock);
228
+		return pid;
229
+	}
230
+	if (pid==0){
231
+		/* wait for parent to get out of critical zone */
232
+		lock_get(process_lock);
233
+			close(sockfd[0]);
234
+			unix_tcp_sock=sockfd[1];
235
+			if (reader_fd_1) *reader_fd_1=reader_fd[1];
236
+		lock_release(process_lock);
237
+		if (init_child(child_id) < 0) {
238
+			LOG(L_ERR, "ERROR: fork_tcp_process(): init_child failed for "
239
+					"%s\n", pt[process_no].desc);
240
+			return -1;
241
+		}
242
+		return pid;
243
+	} else {
244
+		/* parent */		
245
+		process_no = old_process_no;
246
+		/* add the process to the list in shm */
247
+		pt[*process_count].pid=pid;
248
+		pt[*process_count].unix_sock=sockfd[0];
249
+		pt[*process_count].idx=r; 	
250
+		if (desc){
251
+			snprintf(pt[*process_count].desc, MAX_PT_DESC, "%s child=%d", 
252
+						desc, r);
253
+		}
254
+		
255
+		close(sockfd[1]);
256
+		close(reader_fd[1]);
257
+		
258
+		tcp_children[r].pid=pid;
259
+		tcp_children[r].proc_no=process_no;
260
+		tcp_children[r].busy=0;
261
+		tcp_children[r].n_reqs=0;
262
+		tcp_children[r].unix_sock=reader_fd[0];
263
+		
264
+		*process_count = (*process_count) +1;
265
+		lock_release(process_lock);
266
+		return pid;
267
+	}
268
+}
269
+
270
+
271
+