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
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment