diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h index 01d1444..fddfc86 100644 --- a/include/kore/python_methods.h +++ b/include/kore/python_methods.h @@ -32,6 +32,7 @@ struct python_coro { TAILQ_HEAD(coro_list, python_coro); static PyObject *python_kore_log(PyObject *, PyObject *); +static PyObject *python_kore_time(PyObject *, PyObject *); static PyObject *python_kore_lock(PyObject *, PyObject *); static PyObject *python_kore_proc(PyObject *, PyObject *); static PyObject *python_kore_bind(PyObject *, PyObject *); @@ -59,6 +60,7 @@ static PyObject *python_websocket_broadcast(PyObject *, PyObject *); static struct PyMethodDef pykore_methods[] = { METHOD("log", python_kore_log, METH_VARARGS), + METHOD("time", python_kore_time, METH_NOARGS), METHOD("lock", python_kore_lock, METH_NOARGS), METHOD("proc", python_kore_proc, METH_VARARGS), METHOD("bind", python_kore_bind, METH_VARARGS), diff --git a/src/http.c b/src/http.c index 81ea4e7..99d604b 100644 --- a/src/http.c +++ b/src/http.c @@ -1501,6 +1501,10 @@ http_request_new(struct connection *c, const char *host, req->host = host; req->path = path; +#if defined(KORE_USE_PYTHON) + req->py_coro = NULL; +#endif + if (qsoff > 0) { req->query_string = path + qsoff; *(req->query_string)++ = '\0'; diff --git a/src/python.c b/src/python.c index 247b39d..6064ea6 100644 --- a/src/python.c +++ b/src/python.c @@ -324,33 +324,43 @@ kore_python_proc_reap(void) pid_t child; int status; - if ((child = waitpid(-1, &status, 0)) == -1) { - if (errno == ECHILD) + for (;;) { + if ((child = waitpid(-1, &status, WNOHANG)) == -1) { + if (errno == ECHILD) + return; + if (errno == EINTR) + continue; + kore_log(LOG_NOTICE, "waitpid: %s", errno_s); return; - kore_log(LOG_NOTICE, "waitpid: %s", errno_s); - return; + } + + if (child == 0) + return; + + proc = NULL; + + TAILQ_FOREACH(proc, &procs, list) { + if (proc->pid == child) + break; + } + + if (proc == NULL) + continue; + + proc->pid = -1; + proc->reaped = 1; + proc->status = status; + + if (proc->timer != NULL) { + kore_timer_remove(proc->timer); + proc->timer = NULL; + } + + if (proc->coro->request != NULL) + http_request_wakeup(proc->coro->request); + else + python_coro_wakeup(proc->coro); } - - proc = NULL; - - TAILQ_FOREACH(proc, &procs, list) { - if (proc->pid == child) - break; - } - - if (proc == NULL) { - kore_log(LOG_NOTICE, "SIGCHLD for unknown proc (%d)", child); - return; - } - - proc->pid = -1; - proc->reaped = 1; - proc->status = status; - - if (proc->coro->request != NULL) - http_request_wakeup(proc->coro->request); - else - python_coro_wakeup(proc->coro); } static void * @@ -880,6 +890,16 @@ python_kore_log(PyObject *self, PyObject *args) Py_RETURN_TRUE; } +static PyObject * +python_kore_time(PyObject *self, PyObject *args) +{ + u_int64_t now; + + now = kore_time_ms(); + + return (PyLong_FromUnsignedLongLong(now)); +} + static PyObject * python_kore_bind(PyObject *self, PyObject *args) { @@ -1238,11 +1258,8 @@ python_kore_proc(PyObject *self, PyObject *args) close(out_pipe[1]); if (!kore_connection_nonblock(in_pipe[1], 0) || - !kore_connection_nonblock(out_pipe[0], 0)) { - Py_DECREF((PyObject *)proc); - PyErr_SetString(PyExc_RuntimeError, errno_s); - return (NULL); - } + !kore_connection_nonblock(out_pipe[0], 0)) + fatal("failed to mark kore.proc pipes are non-blocking"); proc->in->fd = in_pipe[1]; proc->out->fd = out_pipe[0]; @@ -1705,9 +1722,9 @@ pysocket_op_iternext(struct pysocket_op *op) return (NULL); } - PyErr_SetNone(PyExc_StopIteration); - - return (NULL); + /* Drain the recv socket. */ + op->data.evt.flags |= KORE_EVENT_READ; + return (pysocket_async_recv(op)); } switch (op->data.type) {