|
41 | 41 |
|
42 | 42 | #if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
|
43 | 43 |
|
| 44 | +#include <string.h> |
44 | 45 | #include <poll.h>
|
45 | 46 |
|
46 | 47 | #if !((MP_STREAM_POLL_RD) == (POLLIN) && \
|
@@ -142,14 +143,47 @@ STATIC void poll_obj_set_revents(poll_obj_t *poll_obj, mp_uint_t revents) {
|
142 | 143 | }
|
143 | 144 | }
|
144 | 145 |
|
| 146 | +// How much (in pollfds) to grow the allocation for poll_set->pollfds by. |
| 147 | +#define POLL_SET_ALLOC_INCREMENT (4) |
| 148 | + |
145 | 149 | STATIC struct pollfd *poll_set_add_fd(poll_set_t *poll_set, int fd) {
|
146 | 150 | struct pollfd *free_slot = NULL;
|
147 | 151 |
|
148 | 152 | if (poll_set->used == poll_set->max_used) {
|
149 | 153 | // No free slots below max_used, so expand max_used (and possibly allocate).
|
150 | 154 | if (poll_set->max_used >= poll_set->alloc) {
|
151 |
| - poll_set->pollfds = m_renew(struct pollfd, poll_set->pollfds, poll_set->alloc, poll_set->alloc + 4); |
152 |
| - poll_set->alloc += 4; |
| 155 | + size_t new_alloc = poll_set->alloc + POLL_SET_ALLOC_INCREMENT; |
| 156 | + // Try to grow in-place. |
| 157 | + struct pollfd *new_fds = m_renew_maybe(struct pollfd, poll_set->pollfds, poll_set->alloc, new_alloc, false); |
| 158 | + if (!new_fds) { |
| 159 | + // Failed to grow in-place. Do a new allocation and copy over the pollfd values. |
| 160 | + new_fds = m_new(struct pollfd, new_alloc); |
| 161 | + memcpy(new_fds, poll_set->pollfds, sizeof(struct pollfd) * poll_set->alloc); |
| 162 | + |
| 163 | + // Update existing poll_obj_t to update their pollfd field to |
| 164 | + // point to the same offset inside the new allocation. |
| 165 | + for (mp_uint_t i = 0; i < poll_set->map.alloc; ++i) { |
| 166 | + if (!mp_map_slot_is_filled(&poll_set->map, i)) { |
| 167 | + continue; |
| 168 | + } |
| 169 | + |
| 170 | + poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_set->map.table[i].value); |
| 171 | + if (!poll_obj) { |
| 172 | + // This is the one we're currently adding, |
| 173 | + // poll_set_add_obj doesn't assign elem->value until |
| 174 | + // afterwards. |
| 175 | + continue; |
| 176 | + } |
| 177 | + |
| 178 | + poll_obj->pollfd = new_fds + (poll_obj->pollfd - poll_set->pollfds); |
| 179 | + } |
| 180 | + |
| 181 | + // Delete the old allocation. |
| 182 | + m_del(struct pollfd, poll_set->pollfds, poll_set->alloc); |
| 183 | + } |
| 184 | + |
| 185 | + poll_set->pollfds = new_fds; |
| 186 | + poll_set->alloc = new_alloc; |
153 | 187 | }
|
154 | 188 | free_slot = &poll_set->pollfds[poll_set->max_used++];
|
155 | 189 | } else {
|
|
0 commit comments