Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 1 | /* |
Alexander Steffen | 55f3324 | 2017-06-30 09:22:17 +0200 | [diff] [blame] | 2 | * This file is part of the MicroPython project, http://micropython.org/ |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 3 | * |
| 4 | * The MIT License (MIT) |
| 5 | * |
| 6 | * Copyright (c) 2014 Damien P. George |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 7 | * Copyright (c) 2015-2017 Paul Sokolovsky |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 8 | * |
| 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 10 | * of this software and associated documentation files (the "Software"), to deal |
| 11 | * in the Software without restriction, including without limitation the rights |
| 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 13 | * copies of the Software, and to permit persons to whom the Software is |
| 14 | * furnished to do so, subject to the following conditions: |
| 15 | * |
| 16 | * The above copyright notice and this permission notice shall be included in |
| 17 | * all copies or substantial portions of the Software. |
| 18 | * |
| 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 25 | * THE SOFTWARE. |
| 26 | */ |
| 27 | |
Paul Sokolovsky | 2d11b17 | 2015-12-13 08:47:00 +0200 | [diff] [blame] | 28 | #include "py/mpconfig.h" |
| 29 | |
Paul Sokolovsky | 87dfc76 | 2016-11-21 00:48:55 +0300 | [diff] [blame] | 30 | #if MICROPY_PY_USELECT_POSIX |
Paul Sokolovsky | 2d11b17 | 2015-12-13 08:47:00 +0200 | [diff] [blame] | 31 | |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 32 | #include <stdio.h> |
| 33 | #include <errno.h> |
| 34 | #include <poll.h> |
| 35 | |
Damien George | 503089e | 2016-10-07 14:05:15 +1100 | [diff] [blame] | 36 | #include "py/runtime.h" |
Damien George | ef554ef | 2018-07-20 13:09:49 +1000 | [diff] [blame] | 37 | #include "py/stream.h" |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 38 | #include "py/obj.h" |
| 39 | #include "py/objlist.h" |
| 40 | #include "py/objtuple.h" |
| 41 | #include "py/mphal.h" |
David Lechner | fee7e56 | 2020-01-22 18:14:03 -0600 | [diff] [blame] | 42 | #include "py/mpthread.h" |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 43 | #include "fdfile.h" |
| 44 | |
Paul Sokolovsky | b9580b8 | 2017-11-07 01:13:19 +0200 | [diff] [blame] | 45 | #define DEBUG 0 |
| 46 | |
Renato Aguiar | 081c064 | 2016-09-08 15:13:58 -0700 | [diff] [blame] | 47 | #if MICROPY_PY_SOCKET |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 48 | extern const mp_obj_type_t mp_type_socket; |
Renato Aguiar | 081c064 | 2016-09-08 15:13:58 -0700 | [diff] [blame] | 49 | #endif |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 50 | |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 51 | // Flags for poll() |
| 52 | #define FLAG_ONESHOT (1) |
| 53 | |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 54 | /// \class Poll - poll class |
| 55 | |
| 56 | typedef struct _mp_obj_poll_t { |
| 57 | mp_obj_base_t base; |
| 58 | unsigned short alloc; |
| 59 | unsigned short len; |
| 60 | struct pollfd *entries; |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 61 | mp_obj_t *obj_map; |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 62 | short iter_cnt; |
| 63 | short iter_idx; |
| 64 | int flags; |
| 65 | // callee-owned tuple |
| 66 | mp_obj_t ret_tuple; |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 67 | } mp_obj_poll_t; |
| 68 | |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 69 | STATIC int get_fd(mp_obj_t fdlike) { |
Damien George | 6e30f96 | 2019-01-30 22:05:48 +1100 | [diff] [blame] | 70 | if (mp_obj_is_obj(fdlike)) { |
Damien George | ef554ef | 2018-07-20 13:09:49 +1000 | [diff] [blame] | 71 | const mp_stream_p_t *stream_p = mp_get_stream_raise(fdlike, MP_STREAM_OP_IOCTL); |
| 72 | int err; |
| 73 | mp_uint_t res = stream_p->ioctl(fdlike, MP_STREAM_GET_FILENO, 0, &err); |
| 74 | if (res != MP_STREAM_ERROR) { |
| 75 | return res; |
| 76 | } |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 77 | } |
Damien George | ef554ef | 2018-07-20 13:09:49 +1000 | [diff] [blame] | 78 | return mp_obj_get_int(fdlike); |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 79 | } |
| 80 | |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 81 | /// \method register(obj[, eventmask]) |
Damien George | 4b72b3a | 2016-01-03 14:21:40 +0000 | [diff] [blame] | 82 | STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) { |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 83 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); |
Damien George | 6e30f96 | 2019-01-30 22:05:48 +1100 | [diff] [blame] | 84 | bool is_fd = mp_obj_is_int(args[1]); |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 85 | int fd = get_fd(args[1]); |
| 86 | |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 87 | mp_uint_t flags; |
| 88 | if (n_args == 3) { |
| 89 | flags = mp_obj_get_int(args[2]); |
| 90 | } else { |
| 91 | flags = POLLIN | POLLOUT; |
| 92 | } |
| 93 | |
Paul Sokolovsky | 082b121 | 2015-12-05 14:53:53 +0200 | [diff] [blame] | 94 | struct pollfd *free_slot = NULL; |
| 95 | |
| 96 | struct pollfd *entry = self->entries; |
| 97 | for (int i = 0; i < self->len; i++, entry++) { |
| 98 | int entry_fd = entry->fd; |
| 99 | if (entry_fd == fd) { |
| 100 | entry->events = flags; |
| 101 | return mp_const_false; |
Paul Sokolovsky | 698a6a9 | 2015-11-29 00:05:56 +0200 | [diff] [blame] | 102 | } |
Paul Sokolovsky | 082b121 | 2015-12-05 14:53:53 +0200 | [diff] [blame] | 103 | if (entry_fd == -1) { |
| 104 | free_slot = entry; |
Paul Sokolovsky | 698a6a9 | 2015-11-29 00:05:56 +0200 | [diff] [blame] | 105 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 106 | } |
| 107 | |
Paul Sokolovsky | 082b121 | 2015-12-05 14:53:53 +0200 | [diff] [blame] | 108 | if (free_slot == NULL) { |
| 109 | if (self->len >= self->alloc) { |
| 110 | self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4); |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 111 | if (self->obj_map) { |
| 112 | self->obj_map = m_renew(mp_obj_t, self->obj_map, self->alloc, self->alloc + 4); |
| 113 | } |
Paul Sokolovsky | 082b121 | 2015-12-05 14:53:53 +0200 | [diff] [blame] | 114 | self->alloc += 4; |
| 115 | } |
| 116 | free_slot = &self->entries[self->len++]; |
| 117 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 118 | |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 119 | if (!is_fd) { |
| 120 | if (self->obj_map == NULL) { |
| 121 | self->obj_map = m_new0(mp_obj_t, self->alloc); |
| 122 | } |
| 123 | self->obj_map[free_slot - self->entries] = args[1]; |
| 124 | } |
| 125 | |
Paul Sokolovsky | 082b121 | 2015-12-05 14:53:53 +0200 | [diff] [blame] | 126 | free_slot->fd = fd; |
| 127 | free_slot->events = flags; |
| 128 | free_slot->revents = 0; |
| 129 | return mp_const_true; |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 130 | } |
| 131 | MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register); |
| 132 | |
| 133 | /// \method unregister(obj) |
| 134 | STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) { |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 135 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 136 | struct pollfd *entries = self->entries; |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 137 | int fd = get_fd(obj_in); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 138 | for (int i = self->len - 1; i >= 0; i--) { |
| 139 | if (entries->fd == fd) { |
| 140 | entries->fd = -1; |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 141 | if (self->obj_map) { |
Paul Sokolovsky | 5efd650 | 2016-12-31 11:19:25 +0300 | [diff] [blame] | 142 | self->obj_map[entries - self->entries] = MP_OBJ_NULL; |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 143 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 144 | break; |
| 145 | } |
| 146 | entries++; |
| 147 | } |
| 148 | |
| 149 | // TODO raise KeyError if obj didn't exist in map |
| 150 | return mp_const_none; |
| 151 | } |
| 152 | MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister); |
| 153 | |
| 154 | /// \method modify(obj, eventmask) |
| 155 | STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) { |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 156 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 157 | struct pollfd *entries = self->entries; |
Paul Sokolovsky | a4aaf82 | 2016-08-07 01:21:42 +0300 | [diff] [blame] | 158 | int fd = get_fd(obj_in); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 159 | for (int i = self->len - 1; i >= 0; i--) { |
| 160 | if (entries->fd == fd) { |
| 161 | entries->events = mp_obj_get_int(eventmask_in); |
Paul Sokolovsky | b9bad7f | 2018-09-28 21:49:42 +0300 | [diff] [blame] | 162 | return mp_const_none; |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 163 | } |
| 164 | entries++; |
| 165 | } |
| 166 | |
Paul Sokolovsky | b9bad7f | 2018-09-28 21:49:42 +0300 | [diff] [blame] | 167 | // obj doesn't exist in poller |
| 168 | mp_raise_OSError(MP_ENOENT); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 169 | } |
| 170 | MP_DEFINE_CONST_FUN_OBJ_3(poll_modify_obj, poll_modify); |
| 171 | |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 172 | STATIC int poll_poll_internal(size_t n_args, const mp_obj_t *args) { |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 173 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 174 | |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 175 | // work out timeout (it's given already in ms) |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 176 | int timeout = -1; |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 177 | int flags = 0; |
| 178 | if (n_args >= 2) { |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 179 | if (args[1] != mp_const_none) { |
| 180 | mp_int_t timeout_i = mp_obj_get_int(args[1]); |
| 181 | if (timeout_i >= 0) { |
| 182 | timeout = timeout_i; |
| 183 | } |
| 184 | } |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 185 | if (n_args >= 3) { |
| 186 | flags = mp_obj_get_int(args[2]); |
| 187 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 188 | } |
| 189 | |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 190 | self->flags = flags; |
| 191 | |
David Lechner | fee7e56 | 2020-01-22 18:14:03 -0600 | [diff] [blame] | 192 | MP_THREAD_GIL_EXIT(); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 193 | int n_ready = poll(self->entries, self->len, timeout); |
David Lechner | fee7e56 | 2020-01-22 18:14:03 -0600 | [diff] [blame] | 194 | MP_THREAD_GIL_ENTER(); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 195 | RAISE_ERRNO(n_ready, errno); |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 196 | return n_ready; |
| 197 | } |
| 198 | |
| 199 | /// \method poll([timeout]) |
| 200 | /// Timeout is in milliseconds. |
| 201 | STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) { |
| 202 | int n_ready = poll_poll_internal(n_args, args); |
| 203 | |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 204 | if (n_ready == 0) { |
| 205 | return mp_const_empty_tuple; |
| 206 | } |
| 207 | |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 208 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); |
| 209 | |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 210 | mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL)); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 211 | int ret_i = 0; |
| 212 | struct pollfd *entries = self->entries; |
Paul Sokolovsky | 19920e2 | 2015-11-28 17:34:20 +0200 | [diff] [blame] | 213 | for (int i = 0; i < self->len; i++, entries++) { |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 214 | if (entries->revents != 0) { |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 215 | mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 216 | // If there's an object stored, return it, otherwise raw fd |
Paul Sokolovsky | 5efd650 | 2016-12-31 11:19:25 +0300 | [diff] [blame] | 217 | if (self->obj_map && self->obj_map[i] != MP_OBJ_NULL) { |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 218 | t->items[0] = self->obj_map[i]; |
| 219 | } else { |
| 220 | t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd); |
| 221 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 222 | t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents); |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 223 | ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t); |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 224 | if (self->flags & FLAG_ONESHOT) { |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 225 | entries->events = 0; |
| 226 | } |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 227 | } |
| 228 | } |
| 229 | |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 230 | return MP_OBJ_FROM_PTR(ret_list); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 231 | } |
Paul Sokolovsky | c1481bb | 2015-12-11 23:36:29 +0200 | [diff] [blame] | 232 | MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_poll_obj, 1, 3, poll_poll); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 233 | |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 234 | STATIC mp_obj_t poll_ipoll(size_t n_args, const mp_obj_t *args) { |
| 235 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); |
| 236 | |
| 237 | if (self->ret_tuple == MP_OBJ_NULL) { |
| 238 | self->ret_tuple = mp_obj_new_tuple(2, NULL); |
| 239 | } |
| 240 | |
| 241 | int n_ready = poll_poll_internal(n_args, args); |
| 242 | self->iter_cnt = n_ready; |
| 243 | self->iter_idx = 0; |
| 244 | |
| 245 | return args[0]; |
| 246 | } |
| 247 | MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_ipoll_obj, 1, 3, poll_ipoll); |
| 248 | |
| 249 | STATIC mp_obj_t poll_iternext(mp_obj_t self_in) { |
| 250 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); |
| 251 | |
| 252 | if (self->iter_cnt == 0) { |
| 253 | return MP_OBJ_STOP_ITERATION; |
| 254 | } |
| 255 | |
| 256 | self->iter_cnt--; |
| 257 | |
Paul Sokolovsky | fe866d9 | 2017-03-05 13:51:22 +0100 | [diff] [blame] | 258 | struct pollfd *entries = self->entries + self->iter_idx; |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 259 | for (int i = self->iter_idx; i < self->len; i++, entries++) { |
Paul Sokolovsky | fe866d9 | 2017-03-05 13:51:22 +0100 | [diff] [blame] | 260 | self->iter_idx++; |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 261 | if (entries->revents != 0) { |
| 262 | mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->ret_tuple); |
| 263 | // If there's an object stored, return it, otherwise raw fd |
| 264 | if (self->obj_map && self->obj_map[i] != MP_OBJ_NULL) { |
| 265 | t->items[0] = self->obj_map[i]; |
| 266 | } else { |
| 267 | t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd); |
| 268 | } |
| 269 | t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents); |
| 270 | if (self->flags & FLAG_ONESHOT) { |
| 271 | entries->events = 0; |
| 272 | } |
| 273 | return MP_OBJ_FROM_PTR(t); |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | assert(!"inconsistent number of poll active entries"); |
| 278 | self->iter_cnt = 0; |
| 279 | return MP_OBJ_STOP_ITERATION; |
| 280 | } |
| 281 | |
Paul Sokolovsky | b9580b8 | 2017-11-07 01:13:19 +0200 | [diff] [blame] | 282 | #if DEBUG |
Paul Sokolovsky | cb910c6 | 2017-11-07 00:43:21 +0200 | [diff] [blame] | 283 | STATIC mp_obj_t poll_dump(mp_obj_t self_in) { |
| 284 | mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); |
| 285 | |
| 286 | struct pollfd *entries = self->entries; |
| 287 | for (int i = self->len - 1; i >= 0; i--) { |
| 288 | printf("fd: %d ev: %x rev: %x", entries->fd, entries->events, entries->revents); |
| 289 | if (self->obj_map) { |
| 290 | printf(" obj: %p", self->obj_map[entries - self->entries]); |
| 291 | } |
| 292 | printf("\n"); |
| 293 | entries++; |
| 294 | } |
| 295 | |
| 296 | return mp_const_none; |
| 297 | } |
| 298 | MP_DEFINE_CONST_FUN_OBJ_1(poll_dump_obj, poll_dump); |
Paul Sokolovsky | b9580b8 | 2017-11-07 01:13:19 +0200 | [diff] [blame] | 299 | #endif |
Paul Sokolovsky | cb910c6 | 2017-11-07 00:43:21 +0200 | [diff] [blame] | 300 | |
Damien George | cbf7674 | 2015-11-27 13:38:15 +0000 | [diff] [blame] | 301 | STATIC const mp_rom_map_elem_t poll_locals_dict_table[] = { |
| 302 | { MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&poll_register_obj) }, |
| 303 | { MP_ROM_QSTR(MP_QSTR_unregister), MP_ROM_PTR(&poll_unregister_obj) }, |
| 304 | { MP_ROM_QSTR(MP_QSTR_modify), MP_ROM_PTR(&poll_modify_obj) }, |
| 305 | { MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&poll_poll_obj) }, |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 306 | { MP_ROM_QSTR(MP_QSTR_ipoll), MP_ROM_PTR(&poll_ipoll_obj) }, |
Paul Sokolovsky | b9580b8 | 2017-11-07 01:13:19 +0200 | [diff] [blame] | 307 | #if DEBUG |
| 308 | { MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&poll_dump_obj) }, |
| 309 | #endif |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 310 | }; |
| 311 | STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); |
| 312 | |
| 313 | STATIC const mp_obj_type_t mp_type_poll = { |
| 314 | { &mp_type_type }, |
| 315 | .name = MP_QSTR_poll, |
Damien George | ae8d867 | 2016-01-09 23:14:54 +0000 | [diff] [blame] | 316 | .getiter = mp_identity_getiter, |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 317 | .iternext = poll_iternext, |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame^] | 318 | .locals_dict = (void *)&poll_locals_dict, |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 319 | }; |
| 320 | |
Damien George | 4b72b3a | 2016-01-03 14:21:40 +0000 | [diff] [blame] | 321 | STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) { |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 322 | int alloc = 4; |
| 323 | if (n_args > 0) { |
| 324 | alloc = mp_obj_get_int(args[0]); |
| 325 | } |
| 326 | mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t); |
| 327 | poll->base.type = &mp_type_poll; |
| 328 | poll->entries = m_new(struct pollfd, alloc); |
| 329 | poll->alloc = alloc; |
| 330 | poll->len = 0; |
Paul Sokolovsky | 093a8f5 | 2016-12-31 00:07:18 +0300 | [diff] [blame] | 331 | poll->obj_map = NULL; |
Paul Sokolovsky | 16a3534 | 2017-02-13 00:23:23 +0300 | [diff] [blame] | 332 | poll->iter_cnt = 0; |
| 333 | poll->ret_tuple = MP_OBJ_NULL; |
Damien George | 999cedb | 2015-11-27 17:01:44 +0000 | [diff] [blame] | 334 | return MP_OBJ_FROM_PTR(poll); |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 335 | } |
| 336 | MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_poll_obj, 0, 1, select_poll); |
| 337 | |
Damien George | cbf7674 | 2015-11-27 13:38:15 +0000 | [diff] [blame] | 338 | STATIC const mp_rom_map_elem_t mp_module_select_globals_table[] = { |
| 339 | { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uselect) }, |
| 340 | { MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mp_select_poll_obj) }, |
| 341 | { MP_ROM_QSTR(MP_QSTR_POLLIN), MP_ROM_INT(POLLIN) }, |
| 342 | { MP_ROM_QSTR(MP_QSTR_POLLOUT), MP_ROM_INT(POLLOUT) }, |
| 343 | { MP_ROM_QSTR(MP_QSTR_POLLERR), MP_ROM_INT(POLLERR) }, |
| 344 | { MP_ROM_QSTR(MP_QSTR_POLLHUP), MP_ROM_INT(POLLHUP) }, |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 345 | }; |
| 346 | |
| 347 | STATIC MP_DEFINE_CONST_DICT(mp_module_select_globals, mp_module_select_globals_table); |
| 348 | |
| 349 | const mp_obj_module_t mp_module_uselect = { |
| 350 | .base = { &mp_type_module }, |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame^] | 351 | .globals = (mp_obj_dict_t *)&mp_module_select_globals, |
Paul Sokolovsky | 65971f5 | 2015-11-17 00:35:29 +0200 | [diff] [blame] | 352 | }; |
Paul Sokolovsky | 2d11b17 | 2015-12-13 08:47:00 +0200 | [diff] [blame] | 353 | |
Paul Sokolovsky | 87dfc76 | 2016-11-21 00:48:55 +0300 | [diff] [blame] | 354 | #endif // MICROPY_PY_USELECT_POSIX |