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.
This commit is contained in:
parent
f2d532c404
commit
082b12128d
@ -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 (entries->fd != -1) {
|
||||
i = self->len++;
|
||||
self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4);
|
||||
self->alloc += 4;
|
||||
if (entry_fd == -1) {
|
||||
free_slot = entry;
|
||||
}
|
||||
}
|
||||
|
||||
self->entries[i].fd = mp_obj_get_int(args[1]);
|
||||
self->entries[i].events = flags;
|
||||
self->entries[i].revents = 0;
|
||||
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++];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user