mirror of
https://github.com/jorisvink/kore
synced 2025-03-09 12:39:01 -04:00
Add an optional timeout to socketop.recv().
This commit is contained in:
parent
1e7ccc2adf
commit
f4cd70956b
@ -40,13 +40,21 @@ class EchoServer:
|
||||
kore.fatal("exception %s" % e)
|
||||
|
||||
# Each client will run as this co-routine.
|
||||
# In this case we pass a timeout of 1 second to the recv() call
|
||||
# which will throw a TimeoutError exception in case the timeout
|
||||
# is hit before data is read from the socket.
|
||||
#
|
||||
# This timeout argument is optional. If none is specified the call
|
||||
# will wait until data becomes available.
|
||||
async def handle_client(self, client):
|
||||
while True:
|
||||
try:
|
||||
data = await client.recv(1024)
|
||||
data = await client.recv(1024, 1000)
|
||||
if data is None:
|
||||
break
|
||||
await client.send(data)
|
||||
except TimeoutError as e:
|
||||
print("timed out reading (%s)" % e)
|
||||
except Exception as e:
|
||||
print("client got exception %s" % e)
|
||||
client.close()
|
||||
|
@ -210,6 +210,7 @@ struct pysocket_data {
|
||||
struct kore_buf buffer;
|
||||
struct sockaddr_in sendaddr;
|
||||
struct pysocket *socket;
|
||||
struct kore_timer *timer;
|
||||
};
|
||||
|
||||
struct pysocket_op {
|
||||
|
46
src/python.c
46
src/python.c
@ -50,6 +50,7 @@ static int python_coro_run(struct python_coro *);
|
||||
static void python_coro_wakeup(struct python_coro *);
|
||||
|
||||
static void pysocket_evt_handle(void *, int);
|
||||
static void pysocket_op_timeout(void *, u_int64_t);
|
||||
static PyObject *pysocket_op_create(struct pysocket *,
|
||||
int, const void *, size_t);
|
||||
|
||||
@ -1703,12 +1704,28 @@ pysocket_sendto(struct pysocket *sock, PyObject *args)
|
||||
static PyObject *
|
||||
pysocket_recv(struct pysocket *sock, PyObject *args)
|
||||
{
|
||||
Py_ssize_t len;
|
||||
Py_ssize_t len;
|
||||
struct pysocket_op *op;
|
||||
PyObject *obj;
|
||||
int timeo;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "n", &len))
|
||||
timeo = -1;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "n|i", &len, &timeo))
|
||||
return (NULL);
|
||||
|
||||
return (pysocket_op_create(sock, PYSOCKET_TYPE_RECV, NULL, len));
|
||||
obj = pysocket_op_create(sock, PYSOCKET_TYPE_RECV, NULL, len);
|
||||
if (obj == NULL)
|
||||
return (NULL);
|
||||
|
||||
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 *
|
||||
@ -1826,6 +1843,11 @@ pysocket_op_dealloc(struct pysocket_op *op)
|
||||
op->data.type == PYSOCKET_TYPE_SEND)
|
||||
kore_buf_cleanup(&op->data.buffer);
|
||||
|
||||
if (op->data.timer != NULL) {
|
||||
kore_timer_remove(op->data.timer);
|
||||
op->data.timer = NULL;
|
||||
}
|
||||
|
||||
op->data.coro->sockop = NULL;
|
||||
Py_DECREF(op->data.socket);
|
||||
|
||||
@ -1860,6 +1882,7 @@ pysocket_op_create(struct pysocket *sock, int type, const void *ptr, size_t len)
|
||||
op->data.eof = 0;
|
||||
op->data.self = op;
|
||||
op->data.type = type;
|
||||
op->data.timer = NULL;
|
||||
op->data.socket = sock;
|
||||
op->data.evt.flags = 0;
|
||||
op->data.coro = coro_running;
|
||||
@ -1952,6 +1975,23 @@ pysocket_op_iternext(struct pysocket_op *op)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
pysocket_op_timeout(void *arg, u_int64_t now)
|
||||
{
|
||||
struct pysocket_op *op = arg;
|
||||
|
||||
op->data.eof = 1;
|
||||
op->data.timer = NULL;
|
||||
|
||||
op->data.coro->exception = PyExc_TimeoutError;
|
||||
op->data.coro->exception_msg = "timeout before operation completed";
|
||||
|
||||
if (op->data.coro->request != NULL)
|
||||
http_request_wakeup(op->data.coro->request);
|
||||
else
|
||||
python_coro_wakeup(op->data.coro);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pysocket_async_connect(struct pysocket_op *op)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user