8000 unix/moduselect: If file object passed to .register(), return it in .… · micropython/micropython@093a8f5 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 093a8f5

Browse files
author
Paul Sokolovsky
committed
unix/moduselect: If file object passed to .register(), return it in .poll().
This makes unix "uselect" compatible with baremetal "uselect". Previosuly, unix version accepted file/socket objects, but internally converted that to file descriptors, and that's what .poll() 8000 returned. To acheive new behavior, file-like objects are stored internally in an array, in addition to existing array of struct pollfd. This array is created only on first case of file-like object being passed to .register(). If only raw fd's are passed, there will be no additional memory used comparing to the original implementation.
1 parent d377c83 commit 093a8f5

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

unix/moduselect.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ typedef struct _mp_obj_poll_t {
5454
unsigned short alloc;
5555
unsigned short len;
5656
struct pollfd *entries;
57+
mp_obj_t *obj_map;
5758
} mp_obj_poll_t;
5859

5960
STATIC int get_fd(mp_obj_t fdlike) {
@@ -75,6 +76,7 @@ STATIC int get_fd(mp_obj_t fdlike) {
7576
/// \method register(obj[, eventmask])
7677
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
7778
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
79+
bool is_fd = MP_OBJ_IS_INT(args[1]);
7880
int fd = get_fd(args[1]);
7981

8082
mp_uint_t flags;
@@ -101,11 +103,21 @@ STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
101103
if (free_slot == NULL) {
102104
if (self->len >= self->alloc) {
103105
self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4);
106+
if (self->obj_map) {
107+
self->obj_map = m_renew(mp_obj_t, self->obj_map, self->alloc, self->alloc + 4);
108+
}
104109
self->alloc += 4;
105110
}
106111
free_slot = &self->entries[self->len++];
107112
}
108113

114+
if (!is_fd) {
115+
if (self->obj_map == NULL) {
116+
self->obj_map = m_new0(mp_obj_t, self->alloc);
117+
}
118+
self->obj_map[free_slot - self->entries] = args[1];
119+
}
120+
109121
free_slot->fd = fd;
110122
free_slot->events = flags;
111123
free_slot->revents = 0;
@@ -121,6 +133,9 @@ STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) {
121133
for (int i = self->len - 1; i >= 0; i--) {
122134
if (entries->fd == fd) {
123135
entries->fd = -1;
136+
if (self->obj_map) {
137+
self->obj_map[entries - self->entries] = NULL;
138+
}
124139
break;
125140
}
126141
entries++;
@@ -181,7 +196,12 @@ STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
181196
for (int i = 0; i < self->len; i++, entries++) {
182197
if (entries->revents != 0) {
183198
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
184-
t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd);
199+
// If there's an object stored, return it, otherwise raw fd
200+
if (self->obj_map && self->obj_map[i] != NULL) {
201+
t->items[0] = self->obj_map[i];
202+
} else {
203+
t->items[0] = MP_OBJ_NEW_SMALL_INT(entries->fd);
204+
}
185205
t->items[1] = MP_OBJ_NEW_SMALL_INT(entries->revents);
186206
ret_list->items[ret_i++] = MP_OBJ_FROM_PTR(t);
187207
if (flags & FLAG_ONESHOT) {
@@ -218,6 +238,7 @@ STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) {
218238
poll->entries = m_new(struct pollfd, alloc);
219239
poll->alloc = alloc;
220240
poll->len = 0;
241+
poll->obj_map = NULL;
221242
return MP_OBJ_FROM_PTR(poll);
222243
}
223244
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_poll_obj, 0, 1, select_poll);

0 commit comments

Comments
 (0)
0