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.
This commit is contained in:
Paul Sokolovsky 2015-12-11 23:36:29 +02:00
parent 4651c4381e
commit c1481bb0ab

View file

@ -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) },