commit 1ebd82969c6400e054d0927a55c92a593518383c
parent f4cd70956b754c98a256ce918545df6d398f7167
Author: Joris Vink <joris@coders.se>
Date: Tue, 26 Feb 2019 15:22:55 +0100
Add timeout support to proc.recv()
Diffstat:
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/examples/python-async/src/async_process.py b/examples/python-async/src/async_process.py
@@ -41,9 +41,16 @@ async def async_proc(req):
# Read until EOF (None is returned)
while True:
- chunk = await proc.recv(1024)
- if chunk is None:
- break
+ try:
+ # Read from the process, with an optional 1 second timeout.
+ # The recv() call will throw a TimeoutError exception if
+ # the timeout has elapsed before any data was read.
+ chunk = await proc.recv(1024, 1000)
+ if chunk is None:
+ break
+ except TimeoutError as e:
+ print("recv() timed out: %s" % e)
+ continue
stdout += chunk.decode()
# Reap the process.
diff --git a/src/python.c b/src/python.c
@@ -2574,17 +2574,33 @@ pyproc_reap(struct pyproc *proc, PyObject *args)
static PyObject *
pyproc_recv(struct pyproc *proc, PyObject *args)
{
- Py_ssize_t len;
+ Py_ssize_t len;
+ struct pysocket_op *op;
+ PyObject *obj;
+ int timeo;
+
+ timeo = -1;
if (proc->out == NULL) {
PyErr_SetString(PyExc_RuntimeError, "stdout closed");
return (NULL);
}
- if (!PyArg_ParseTuple(args, "n", &len))
+ if (!PyArg_ParseTuple(args, "n|i", &len, &timeo))
+ return (NULL);
+
+ obj = pysocket_op_create(proc->out, PYSOCKET_TYPE_RECV, NULL, len);
+ if (obj == NULL)
return (NULL);
- return (pysocket_op_create(proc->out, PYSOCKET_TYPE_RECV, NULL, len));
+ op = (struct pysocket_op *)obj;
+
+ if (timeo != -1) {
+ op->data.timer = kore_timer_add(pysocket_op_timeout,
+ timeo, op, KORE_TIMER_ONESHOT);
+ }
+
+ return (obj);
}
static PyObject *