From c1481bb0ab3c7aa53963e15113dab12dca73693d Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 11 Dec 2015 23:36:29 +0200 Subject: [PATCH] unix/moduselect: Implement "one-shot" flag for poll.poll(). After an I/O event is triggered for fd, event flags are automatically reset, so no further events are reported until new event flags are set. This is an optimization for uasyncio, required to account for coroutine semantics: each coroutine issues explicit read/write async call, and once that trigger, no events should be reported to coroutine, unless it again explicitly requests it. One-shot mode saves one linear scan over the poll array. --- unix/moduselect.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/unix/moduselect.c b/unix/moduselect.c index b86084b184..6a01325a1d 100644 --- a/unix/moduselect.c +++ b/unix/moduselect.c @@ -35,6 +35,9 @@ #include "py/objtuple.h" #include "py/mphal.h" +// Flags for poll() +#define FLAG_ONESHOT (1) + /// \class Poll - poll class typedef struct _mp_obj_poll_t { @@ -125,15 +128,19 @@ MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify); STATIC mp_obj_t poll_poll(uint n_args, const mp_obj_t *args) { mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); - // work out timeout (its given already in ms) + // work out timeout (it's given already in ms) int timeout = -1; - if (n_args == 2) { + int flags = 0; + if (n_args >= 2) { if (args[1] != mp_const_none) { mp_int_t timeout_i = mp_obj_get_int(args[1]); if (timeout_i >= 0) { timeout = timeout_i; } } + if (n_args >= 3) { + flags = mp_obj_get_int(args[2]); + } } int n_ready = poll(self->entries, self->len, timeout); @@ -151,12 +158,15 @@ STATIC mp_obj_t poll_poll(uint n_args, const mp_obj_t *args) { t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd); t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents); ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t); + if (flags & FLAG_ONESHOT) { + entries->events = 0; + } } } return MP_OBJ_FROM_PTR(ret_list); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 2, poll_poll); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll); STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) },