aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2018-07-20 13:09:49 +1000
committerDamien George2018-07-20 13:09:49 +1000
commitef554ef9a2708a8f344f22e586f52fb1343ed524 (patch)
tree5a58c900a9cfa79a62f3d332f2ff50f7d80f2128
parent7a4f1b00f6dc279419ef72f4156480b4b84b1108 (diff)
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.
-rw-r--r--ports/unix/file.c2
-rw-r--r--ports/unix/moduselect.c21
-rw-r--r--ports/unix/modusocket.c3
3 files changed, 14 insertions, 12 deletions
diff --git a/ports/unix/file.c b/ports/unix/file.c
index 165bbd00b..a54d1d03d 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 1ea7dc19a..4fa8d3ae8 100644
--- a/ports/unix/moduselect.c
+++ b/ports/unix/moduselect.c
@@ -34,6 +34,7 @@
#include <poll.h>
#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 ba50e6165..5458267a0 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;