|
@@ -21,36 +21,18 @@
|
21
|
21
|
|
22
|
22
|
static int worker_piper_sigrcv = 0;
|
23
|
23
|
|
24
|
|
-pid_t spawn(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
25
|
|
-{
|
26
|
|
- pid_t res;
|
27
|
|
-
|
28
|
|
- res = fork();
|
29
|
|
- if(res == -1)
|
30
|
|
- {
|
31
|
|
- syslog( LOG_ERR, "Fork fails for worker #%d : %s",
|
32
|
|
- wrk_id, strerror(errno));
|
33
|
|
- return -1;
|
34
|
|
- }
|
35
|
|
- else if(!res)
|
36
|
|
- {
|
37
|
|
- // Child process
|
38
|
|
- exit(work(py_entrypoint, wrk_id, semid, max_reqs));
|
39
|
|
- }
|
40
|
|
- syslog( LOG_INFO,
|
41
|
|
- "Worker #%d spawned with PID %d", wrk_id, res);
|
42
|
|
- return res;
|
43
|
|
-}
|
44
|
|
-
|
45
|
24
|
int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
46
|
25
|
{
|
47
|
26
|
PyObject *entry_fun, *pystdout_flush, *pystderr_flush,
|
48
|
27
|
*py_osmod;
|
49
|
28
|
int count, pipe_out[2], pipe_err[2], pipe_ctl[2], err, piper_status;
|
|
29
|
+ struct sembuf sop;
|
50
|
30
|
struct sigaction act;
|
51
|
31
|
sigset_t emptyset;
|
52
|
32
|
char buf[PIPE_BUF];
|
53
|
33
|
|
|
34
|
+ sop.sem_num = 0;
|
|
35
|
+ sop.sem_flg = 0;
|
54
|
36
|
|
55
|
37
|
// preparing sigaction for piper
|
56
|
38
|
if(sigemptyset(&emptyset))
|
|
@@ -96,12 +78,22 @@ int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
96
|
78
|
count = 0;
|
97
|
79
|
while ((!count || count != max_reqs) && FCGI_Accept() >= 0)
|
98
|
80
|
{
|
|
81
|
+ sop.sem_op = -1; // decrementing sem to show worker busy
|
|
82
|
+ if(semop(semid, &sop, 1) < 0)
|
|
83
|
+ {
|
|
84
|
+ err = errno;
|
|
85
|
+ syslog(LOG_ERR,
|
|
86
|
+ "Worker[%d] error decrementing the semaphore : %s",
|
|
87
|
+ wrk_id, strerror(err));
|
|
88
|
+ }
|
|
89
|
+
|
99
|
90
|
count++;
|
|
91
|
+ /*
|
100
|
92
|
syslog( LOG_INFO,
|
101
|
93
|
"Worker[%d] request %d", wrk_id, count);
|
|
94
|
+ */
|
102
|
95
|
worker_piper_sigrcv = 0;
|
103
|
96
|
pipe(pipe_ctl); //TODO : check for pipe error
|
104
|
|
- //PyOS_BeforeFork();
|
105
|
97
|
pid_t pid = fork();
|
106
|
98
|
if(pid < 0)
|
107
|
99
|
{
|
|
@@ -128,7 +120,6 @@ int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
128
|
120
|
//printf("Content-type: text/html\r\n\r\nHello world !\n");
|
129
|
121
|
exit(1);
|
130
|
122
|
}
|
131
|
|
- //PyOS_AfterFork_Parent();
|
132
|
123
|
update_pyenv(py_osmod);
|
133
|
124
|
//TODO : check if pipe_ctl lock is really needed anymore
|
134
|
125
|
close(pipe_ctl[1]);
|
|
@@ -139,14 +130,16 @@ int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
139
|
130
|
}
|
140
|
131
|
else
|
141
|
132
|
{
|
|
133
|
+ /*
|
142
|
134
|
syslog(LOG_DEBUG, "Worker[%d] request %d funcall [OK]",
|
143
|
135
|
wrk_id, count);
|
|
136
|
+ */
|
144
|
137
|
}
|
145
|
138
|
PyObject_CallObject(pystdout_flush, NULL);
|
146
|
139
|
PyObject_CallObject(pystderr_flush, NULL);
|
147
|
140
|
read(pipe_ctl[0], &buf, 1); // unblock when child ready
|
148
|
|
-syslog(LOG_DEBUG, "PIPER UNLOCK");
|
149
|
|
- kill(pid, WPIPER_SIG);
|
|
141
|
+
|
|
142
|
+ kill(pid, WPIPER_SIG); //indicate child python call ended
|
150
|
143
|
waitpid(pid, &piper_status, 0);
|
151
|
144
|
if(piper_status)
|
152
|
145
|
{
|
|
@@ -154,6 +147,17 @@ syslog(LOG_DEBUG, "PIPER UNLOCK");
|
154
|
147
|
"Woker[%d] req #%d piper exited with error status %d",
|
155
|
148
|
wrk_id, count, piper_status);
|
156
|
149
|
}
|
|
150
|
+
|
|
151
|
+ //Increase sem showing the worker is idle
|
|
152
|
+ sop.sem_op = 1;
|
|
153
|
+ if(semop(semid, &sop, 1) < 0)
|
|
154
|
+ {
|
|
155
|
+ err = errno;
|
|
156
|
+ syslog(LOG_ERR,
|
|
157
|
+ "Worker[%d] error incrementing the semaphore : %s",
|
|
158
|
+ wrk_id, strerror(err));
|
|
159
|
+ }
|
|
160
|
+
|
157
|
161
|
syslog(LOG_DEBUG, "Worker[%d] request %d END [OK]",
|
158
|
162
|
wrk_id, count);
|
159
|
163
|
}
|
|
@@ -168,7 +172,7 @@ void worker_piper(int wrk_id, int req_id, int pystdout, int pystderr,
|
168
|
172
|
short revents;
|
169
|
173
|
char buf[PIPE_BUF];
|
170
|
174
|
|
171
|
|
- syslog(LOG_DEBUG, "Worker[%d] req #%d piper", wrk_id, req_id);
|
|
175
|
+ //syslog(LOG_DEBUG, "Worker[%d] req #%d piper", wrk_id, req_id);
|
172
|
176
|
|
173
|
177
|
fds[0].fd = pystdout;
|
174
|
178
|
fds[1].fd = pystderr;
|
|
@@ -180,7 +184,7 @@ void worker_piper(int wrk_id, int req_id, int pystdout, int pystderr,
|
180
|
184
|
while(cont)
|
181
|
185
|
{
|
182
|
186
|
poll_ret = poll(fds, 2, 10);
|
183
|
|
-syslog(LOG_DEBUG, "Worler[%d] req #%d poll_ret = %d", wrk_id, req_id, poll_ret);
|
|
187
|
+//syslog(LOG_DEBUG, "Worker[%d] req #%d poll_ret = %d", wrk_id, req_id, poll_ret);
|
184
|
188
|
if(poll_ret < 0)
|
185
|
189
|
{
|
186
|
190
|
err = errno;
|
|
@@ -200,16 +204,22 @@ syslog(LOG_DEBUG, "Worler[%d] req #%d poll_ret = %d", wrk_id, req_id, poll_ret);
|
200
|
204
|
}
|
201
|
205
|
if(poll_ret && (revents = fds[0].revents))
|
202
|
206
|
{
|
|
207
|
+ /*
|
203
|
208
|
syslog(LOG_DEBUG, "Worker[%d] req #%d STDOUT evt !",
|
204
|
209
|
wrk_id, req_id);
|
|
210
|
+ */
|
205
|
211
|
poll_ret--;
|
206
|
212
|
if(revents & POLLIN)
|
207
|
213
|
{
|
|
214
|
+ /*
|
208
|
215
|
syslog(LOG_DEBUG, "Worker[%d] req #%d POLLIN STDOUT !",
|
209
|
216
|
wrk_id, req_id);
|
|
217
|
+ */
|
210
|
218
|
ret = read(pystdout, buf, PIPE_BUF);
|
|
219
|
+ /*
|
211
|
220
|
syslog(LOG_DEBUG, "Worker[%d] req #%d read(stdout) ret %d",
|
212
|
221
|
wrk_id, req_id, ret);
|
|
222
|
+ */
|
213
|
223
|
if(ret < 0)
|
214
|
224
|
{
|
215
|
225
|
err = errno;
|
|
@@ -229,12 +239,16 @@ syslog(LOG_DEBUG, "Worler[%d] req #%d poll_ret = %d", wrk_id, req_id, poll_ret);
|
229
|
239
|
}
|
230
|
240
|
if(poll_ret && (revents = fds[1].revents))
|
231
|
241
|
{
|
|
242
|
+ /*
|
232
|
243
|
syslog(LOG_DEBUG, "Worker[%d] req #%d STDERR evt !",
|
233
|
244
|
wrk_id, req_id);
|
|
245
|
+ */
|
234
|
246
|
if(revents & POLLIN)
|
235
|
247
|
{
|
|
248
|
+ /*
|
236
|
249
|
syslog(LOG_DEBUG, "Worker[%d] req #%d POLLIN STDERR !",
|
237
|
250
|
wrk_id, req_id);
|
|
251
|
+ */
|
238
|
252
|
while(1)
|
239
|
253
|
{
|
240
|
254
|
ret = read(pystderr, buf, PIPE_BUF);
|
|
@@ -261,8 +275,10 @@ syslog(LOG_DEBUG, "Worler[%d] req #%d poll_ret = %d", wrk_id, req_id, poll_ret);
|
261
|
275
|
}
|
262
|
276
|
fds[0].revents = fds[1].revents = 0;
|
263
|
277
|
}
|
|
278
|
+ /*
|
264
|
279
|
syslog(LOG_DEBUG, "Worker[%d] req #%d piper exiting...",
|
265
|
280
|
wrk_id, req_id);
|
|
281
|
+ */
|
266
|
282
|
exit(0);
|
267
|
283
|
}
|
268
|
284
|
|
|
@@ -620,7 +636,7 @@ void update_pyenv(PyObject *py_osmod)
|
620
|
636
|
}
|
621
|
637
|
value++;
|
622
|
638
|
*(value-1) = '\0'; // dirty modification of **environ
|
623
|
|
-syslog(LOG_DEBUG, "PySetEnv '%s'='%s'", key, value);
|
|
639
|
+//syslog(LOG_DEBUG, "PySetEnv '%s'='%s'", key, value);
|
624
|
640
|
pykey = PyUnicode_DecodeLocale(key, "surrogateescape");
|
625
|
641
|
if(!pykey)
|
626
|
642
|
{
|