Commit c1481bb0 authored by Paul Sokolovsky's avatar Paul Sokolovsky
Browse files

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.
parent 4651c438
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include "py/objtuple.h" #include "py/objtuple.h"
#include "py/mphal.h" #include "py/mphal.h"
// Flags for poll()
#define FLAG_ONESHOT (1)
/// \class Poll - poll class /// \class Poll - poll class
typedef struct _mp_obj_poll_t { typedef struct _mp_obj_poll_t {
...@@ -125,15 +128,19 @@ MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify); ...@@ -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) { 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]); 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; int timeout = -1;
if (n_args == 2) { int flags = 0;
if (n_args >= 2) {
if (args[1] != mp_const_none) { if (args[1] != mp_const_none) {
mp_int_t timeout_i = mp_obj_get_int(args[1]); mp_int_t timeout_i = mp_obj_get_int(args[1]);
if (timeout_i >= 0) { if (timeout_i >= 0) {
timeout = timeout_i; timeout = timeout_i;
} }
} }
if (n_args >= 3) {
flags = mp_obj_get_int(args[2]);
}
} }
int n_ready = poll(self->entries, self->len, timeout); 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) { ...@@ -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[0] = MP_OBJ_NEW_SMALL_INT(entries->fd);
t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents); t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents);
ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t); ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t);
if (flags & FLAG_ONESHOT) {
entries->events = 0;
}
} }
} }
return MP_OBJ_FROM_PTR(ret_list); 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[] = { STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) }, { MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment