|
@@ -44,7 +44,7 @@ pid_t spawn(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
44
|
44
|
|
45
|
45
|
int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
46
|
46
|
{
|
47
|
|
- PyObject *entry_fun;
|
|
47
|
+ PyObject *entry_fun, *pystdout_flush, *pystderr_flush;
|
48
|
48
|
int count, pipe_out[2], pipe_err[2], pipe_ctl[2], err, piper_status;
|
49
|
49
|
struct sigaction act;
|
50
|
50
|
sigset_t emptyset;
|
|
@@ -71,6 +71,7 @@ int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
71
|
71
|
update_python_path(); // add cwd to python path
|
72
|
72
|
Py_Initialize(); // "start" python
|
73
|
73
|
update_python_fd(pipe_out, pipe_err);
|
|
74
|
+ fetch_pyflush(&pystdout_flush, &pystderr_flush);
|
74
|
75
|
syslog( LOG_INFO,
|
75
|
76
|
"Worker[%d] Python started", wrk_id);
|
76
|
77
|
|
|
@@ -128,7 +129,8 @@ int work(char* py_entrypoint, int wrk_id, int semid, int max_reqs)
|
128
|
129
|
syslog(LOG_DEBUG, "Worker[%d] request %d funcall [OK]",
|
129
|
130
|
wrk_id, count);
|
130
|
131
|
}
|
131
|
|
- //TODO : flush pystdout & pystderr using python
|
|
132
|
+ PyObject_CallObject(pystdout_flush, NULL);
|
|
133
|
+ PyObject_CallObject(pystderr_flush, NULL);
|
132
|
134
|
read(pipe_ctl[0], &buf, 1); // unblock when child ready
|
133
|
135
|
syslog(LOG_DEBUG, "PIPER UNLOCK");
|
134
|
136
|
kill(pid, WPIPER_SIG);
|
|
@@ -303,6 +305,40 @@ PyObject* import_entrypoint(char* py_entrypoint)
|
303
|
305
|
return entry_fun;
|
304
|
306
|
}
|
305
|
307
|
|
|
308
|
+static PyObject* _fetch_pyflush(const char *fdname)
|
|
309
|
+{
|
|
310
|
+ PyObject *pyfd, *pyflush;
|
|
311
|
+ pyfd = PySys_GetObject(fdname);
|
|
312
|
+ if(!pyfd)
|
|
313
|
+ {
|
|
314
|
+ syslog(LOG_ALERT, "Unable to fetch sys.%s", fdname);
|
|
315
|
+ log_expt(LOG_ALERT);
|
|
316
|
+ Py_Exit(EXIT_PYERR);
|
|
317
|
+ }
|
|
318
|
+ pyflush = PyObject_GetAttrString(pyfd, "flush");
|
|
319
|
+ Py_DECREF(pyfd);
|
|
320
|
+ if(!pyflush)
|
|
321
|
+ {
|
|
322
|
+ syslog(LOG_ALERT, "Unable to fetch sys.%s.flush", fdname);
|
|
323
|
+ log_expt(LOG_ALERT);
|
|
324
|
+ Py_Exit(EXIT_PYERR);
|
|
325
|
+ }
|
|
326
|
+ if(!PyCallable_Check(pyflush))
|
|
327
|
+ {
|
|
328
|
+ syslog(LOG_ALERT, "sys.%s.flush is not callable !",
|
|
329
|
+ fdname);
|
|
330
|
+ Py_Exit(EXIT_PYERR);
|
|
331
|
+ }
|
|
332
|
+
|
|
333
|
+ return pyflush;
|
|
334
|
+}
|
|
335
|
+
|
|
336
|
+void fetch_pyflush(PyObject** pystdout_flush, PyObject** pystderr_flush)
|
|
337
|
+{
|
|
338
|
+ *pystdout_flush = _fetch_pyflush("stdout");
|
|
339
|
+ *pystderr_flush = _fetch_pyflush("stderr");
|
|
340
|
+}
|
|
341
|
+
|
306
|
342
|
void update_python_path()
|
307
|
343
|
{
|
308
|
344
|
wchar_t *ppath, *wcwd, *wtmp;
|