Skip to content
Snippets Groups Projects
Commit 082b1212 authored by Paul Sokolovsky's avatar Paul Sokolovsky
Browse files

unix/moduselect: register(): Allow to call with duplicate file descriptor.

Per CPython docs, "Registering a file descriptor that’s already registered
is not an error, and has the same effect as registering the descriptor
exactly once."
https://docs.python.org/3/library/select.html#select.poll.register

That's somewhat ambiguous, what's implemented here is that if fd si not
yet registered, it is registered. Otherwise, the effect is equivalent to
modify() method.
parent f2d532c4
No related branches found
No related tags found
No related merge requests found
......@@ -47,6 +47,7 @@ typedef struct _mp_obj_poll_t {
/// \method register(obj[, eventmask])
STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) {
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
int fd = mp_obj_get_int(args[1]);
mp_uint_t flags;
if (n_args == 3) {
flags = mp_obj_get_int(args[2]);
......@@ -54,28 +55,32 @@ STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) {
flags = POLLIN | POLLOUT;
}
int i = 0;
if (self->len < self->alloc) {
i = self->len++;
} else {
struct pollfd *entries = self->entries;
for (i = 0; i < self->len; i++, entries++) {
if (entries->fd == -1) {
break;
struct pollfd *free_slot = NULL;
struct pollfd *entry = self->entries;
for (int i = 0; i < self->len; i++, entry++) {
int entry_fd = entry->fd;
if (entry_fd == fd) {
entry->events = flags;
return mp_const_false;
}
if (entry_fd == -1) {
free_slot = entry;
}
if (entries->fd != -1) {
i = self->len++;
}
if (free_slot == NULL) {
if (self->len >= self->alloc) {
self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4);
self->alloc += 4;
}
free_slot = &self->entries[self->len++];
}
self->entries[i].fd = mp_obj_get_int(args[1]);
self->entries[i].events = flags;
self->entries[i].revents = 0;
return mp_const_none;
free_slot->fd = fd;
free_slot->events = flags;
free_slot->revents = 0;
return mp_const_true;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment