From ef554ef9a2708a8f344f22e586f52fb1343ed524 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 20 Jul 2018 13:09:49 +1000 Subject: [PATCH] unix: Use MP_STREAM_GET_FILENO to allow uselect to poll general objects. This mechanism will scale to to an arbitrary number of pollable objects, so long as they implement the MP_STREAM_GET_FILENO ioctl. Since ussl objects pass through ioctl requests transparently to the underlying socket object, it will allow ussl sockets to be polled. And a user object with uio.IOBase as a base could support polling. --- ports/unix/file.c | 2 ++ ports/unix/moduselect.c | 21 +++++++++------------ ports/unix/modusocket.c | 3 +++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ports/unix/file.c b/ports/unix/file.c index 165bbd00b0..a54d1d03df 100644 --- a/ports/unix/file.c +++ b/ports/unix/file.c @@ -124,6 +124,8 @@ STATIC mp_uint_t fdfile_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i o->fd = -1; #endif return 0; + case MP_STREAM_GET_FILENO: + return o->fd; default: *errcode = EINVAL; return MP_STREAM_ERROR; diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index 1ea7dc19a5..4fa8d3ae80 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -34,6 +34,7 @@ #include #include "py/runtime.h" +#include "py/stream.h" #include "py/obj.h" #include "py/objlist.h" #include "py/objtuple.h" @@ -65,19 +66,15 @@ typedef struct _mp_obj_poll_t { } mp_obj_poll_t; STATIC int get_fd(mp_obj_t fdlike) { - int fd; - // Shortcut for fdfile compatible types - if (MP_OBJ_IS_TYPE(fdlike, &mp_type_fileio) - #if MICROPY_PY_SOCKET - || MP_OBJ_IS_TYPE(fdlike, &mp_type_socket) - #endif - ) { - mp_obj_fdfile_t *fdfile = MP_OBJ_TO_PTR(fdlike); - fd = fdfile->fd; - } else { - fd = mp_obj_get_int(fdlike); + if (MP_OBJ_IS_OBJ(fdlike)) { + const mp_stream_p_t *stream_p = mp_get_stream_raise(fdlike, MP_STREAM_OP_IOCTL); + int err; + mp_uint_t res = stream_p->ioctl(fdlike, MP_STREAM_GET_FILENO, 0, &err); + if (res != MP_STREAM_ERROR) { + return res; + } } - return fd; + return mp_obj_get_int(fdlike); } /// \method register(obj[, eventmask]) diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index ba50e6165e..5458267a05 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -123,6 +123,9 @@ STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i close(self->fd); return 0; + case MP_STREAM_GET_FILENO: + return self->fd; + default: *errcode = MP_EINVAL; return MP_STREAM_ERROR;