@@ -88,8 +88,9 @@ typedef struct _poll_set_t {
88
88
89
89
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
90
90
// Array of pollfd entries for objects that have a file descriptor.
91
- unsigned short alloc ;
92
- unsigned short len ;
91
+ unsigned short alloc ; // memory allocated for pollfds
92
+ unsigned short max_used ; // maximum number of used entries in pollfds
93
+ unsigned short used ; // actual number of used entries in pollfds
93
94
struct pollfd * pollfds ;
94
95
#endif
95
96
} poll_set_t ;
@@ -98,7 +99,8 @@ STATIC void poll_set_init(poll_set_t *poll_set, size_t n) {
98
99
mp_map_init (& poll_set -> map , n );
99
100
#if MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
100
101
poll_set -> alloc = 0 ;
101
- poll_set -> len = 0 ;
102
+ poll_set -> max_used = 0 ;
103
+ poll_set -> used = 0 ;
102
104
poll_set -> pollfds = NULL ;
103
105
#endif
104
106
}
@@ -142,29 +144,34 @@ STATIC void poll_obj_set_revents(poll_obj_t *poll_obj, mp_uint_t revents) {
142
144
143
145
STATIC struct pollfd * poll_set_add_fd (poll_set_t * poll_set , int fd ) {
144
146
struct pollfd * free_slot = NULL ;
145
- for (unsigned int i = 0 ; i < poll_set -> len ; ++ i ) {
146
- struct pollfd * slot = & poll_set -> pollfds [i ];
147
- if (slot -> fd == -1 ) {
148
- free_slot = slot ;
149
- break ;
150
- }
151
- }
152
147
153
- if (free_slot == NULL ) {
154
- if (poll_set -> len >= poll_set -> alloc ) {
148
+ if (poll_set -> used == poll_set -> max_used ) {
149
+ // No free slots below max_used, so expand max_used (and possibly allocate).
150
+ if (poll_set -> max_used >= poll_set -> alloc ) {
155
151
poll_set -> pollfds = m_renew (struct pollfd , poll_set -> pollfds , poll_set -> alloc , poll_set -> alloc + 4 );
156
152
poll_set -> alloc += 4 ;
157
153
}
158
- free_slot = & poll_set -> pollfds [poll_set -> len ++ ];
154
+ free_slot = & poll_set -> pollfds [poll_set -> max_used ++ ];
155
+ } else {
156
+ // There should be a free slot below max_used.
157
+ for (unsigned int i = 0 ; i < poll_set -> max_used ; ++ i ) {
158
+ struct pollfd * slot = & poll_set -> pollfds [i ];
159
+ if (slot -> fd == -1 ) {
160
+ free_slot = slot ;
161
+ break ;
162
+ }
163
+ }
164
+ assert (free_slot != NULL );
159
165
}
160
166
161
167
free_slot -> fd = fd ;
168
+ ++ poll_set -> used ;
162
169
163
170
return free_slot ;
164
171
}
165
172
166
173
static inline bool poll_set_all_are_fds (poll_set_t * poll_set ) {
167
- return poll_set -> map .used == poll_set -> len ;
174
+ return poll_set -> map .used == poll_set -> used ;
168
175
}
169
176
170
177
#else
@@ -323,7 +330,7 @@ STATIC mp_uint_t poll_set_poll_until_ready_or_timeout(poll_set_t *poll_set, size
323
330
}
324
331
325
332
// Call system poll for those objects that have a file descriptor.
326
- int n_ready = poll (poll_set -> pollfds , poll_set -> len , t );
333
+ int n_ready = poll (poll_set -> pollfds , poll_set -> max_used , t );
327
334
328
335
MP_THREAD_GIL_ENTER ();
329
336
@@ -462,6 +469,7 @@ STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
462
469
poll_obj_t * poll_obj = (poll_obj_t * )MP_OBJ_TO_PTR (elem -> value );
463
470
if (poll_obj -> pollfd != NULL ) {
464
471
poll_obj -> pollfd -> fd = -1 ;
472
+ -- self -> poll_set .used ;
465
473
}
466
474
elem -> value = MP_OBJ_NULL ;
467
475
}
0 commit comments