STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) { mp_obj_poll_t *self = args[0]; // work out timeout (its given already in ms) mp_uint_t timeout = -1; 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]); } } self->flags = flags; mp_uint_t start_tick = mp_hal_ticks_ms(); mp_uint_t n_ready; for (;;) { // poll the objects n_ready = poll_map_poll(&self->poll_map, NULL); if (n_ready > 0 || (timeout != -1 && mp_hal_ticks_ms() - start_tick >= timeout)) { break; } MICROPY_EVENT_POLL_HOOK } return n_ready; }
/// \method poll([timeout]) /// Timeout is in milliseconds. STATIC mp_obj_t poll_poll(uint n_args, const mp_obj_t *args) { mp_obj_poll_t *self = args[0]; // work out timeout (its given already in ms) mp_uint_t timeout = -1; 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; } } } mp_uint_t start_tick = HAL_GetTick(); for (;;) { // poll the objects mp_uint_t n_ready = poll_map_poll(&self->poll_map, NULL); if (n_ready > 0 || (timeout != -1 && HAL_GetTick() - start_tick >= timeout)) { // one or more objects are ready, or we had a timeout mp_obj_list_t *ret_list = mp_obj_new_list(n_ready, NULL); mp_uint_t n_ready = 0; for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) { if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) { continue; } poll_obj_t *poll_obj = (poll_obj_t*)self->poll_map.table[i].value; if (poll_obj->flags_ret != 0) { mp_obj_t tuple[2] = {poll_obj->obj, MP_OBJ_NEW_SMALL_INT(poll_obj->flags_ret)}; ret_list->items[n_ready++] = mp_obj_new_tuple(2, tuple); } } return ret_list; } __WFI(); } }
/// \function select(rlist, wlist, xlist[, timeout]) STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) { // get array data from tuple/list arguments mp_uint_t rwx_len[3]; mp_obj_t *r_array, *w_array, *x_array; mp_obj_get_array(args[0], &rwx_len[0], &r_array); mp_obj_get_array(args[1], &rwx_len[1], &w_array); mp_obj_get_array(args[2], &rwx_len[2], &x_array); // get timeout mp_uint_t timeout = -1; if (n_args == 4) { if (args[3] != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT float timeout_f = mp_obj_get_float(args[3]); if (timeout_f >= 0) { timeout = (mp_uint_t)(timeout_f * 1000); } #else timeout = mp_obj_get_int(args[3]) * 1000; #endif } } // merge separate lists and get the ioctl function for each object mp_map_t poll_map; mp_map_init(&poll_map, rwx_len[0] + rwx_len[1] + rwx_len[2]); poll_map_add(&poll_map, r_array, rwx_len[0], MP_IOCTL_POLL_RD, true); poll_map_add(&poll_map, w_array, rwx_len[1], MP_IOCTL_POLL_WR, true); poll_map_add(&poll_map, x_array, rwx_len[2], MP_IOCTL_POLL_ERR | MP_IOCTL_POLL_HUP, true); mp_uint_t start_tick = HAL_GetTick(); rwx_len[0] = rwx_len[1] = rwx_len[2] = 0; for (;;) { // poll the objects mp_uint_t n_ready = poll_map_poll(&poll_map, rwx_len); if (n_ready > 0 || (timeout != -1 && HAL_GetTick() - start_tick >= timeout)) { // one or more objects are ready, or we had a timeout mp_obj_t list_array[3]; list_array[0] = mp_obj_new_list(rwx_len[0], NULL); list_array[1] = mp_obj_new_list(rwx_len[1], NULL); list_array[2] = mp_obj_new_list(rwx_len[2], NULL); rwx_len[0] = rwx_len[1] = rwx_len[2] = 0; for (mp_uint_t i = 0; i < poll_map.alloc; ++i) { if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) { continue; } poll_obj_t *poll_obj = (poll_obj_t*)poll_map.table[i].value; if (poll_obj->flags_ret & MP_IOCTL_POLL_RD) { ((mp_obj_list_t*)list_array[0])->items[rwx_len[0]++] = poll_obj->obj; } if (poll_obj->flags_ret & MP_IOCTL_POLL_WR) { ((mp_obj_list_t*)list_array[1])->items[rwx_len[1]++] = poll_obj->obj; } if ((poll_obj->flags_ret & ~(MP_IOCTL_POLL_RD | MP_IOCTL_POLL_WR)) != 0) { ((mp_obj_list_t*)list_array[2])->items[rwx_len[2]++] = poll_obj->obj; } } mp_map_deinit(&poll_map); return mp_obj_new_tuple(3, list_array); } __WFI(); } }