From 35f66d38b8e153399b5d277b6e02ea1a98eccee1 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 23 Jan 2020 21:50:53 -0600 Subject: [PATCH] extmod/vfs_posix: Release GIL during system calls. This releases the GIL during syscalls that could block. --- extmod/vfs_posix.c | 20 ++++++++++++++++++-- extmod/vfs_posix_file.c | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index d943e0c803..22471e48f3 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -26,6 +26,7 @@ #include "py/runtime.h" #include "py/mperrno.h" +#include "py/mpthread.h" #include "extmod/vfs.h" #include "extmod/vfs_posix.h" @@ -170,12 +171,15 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) { } for (;;) { + MP_THREAD_GIL_EXIT(); struct dirent *dirent = readdir(self->dir); if (dirent == NULL) { closedir(self->dir); + MP_THREAD_GIL_ENTER(); self->dir = NULL; return MP_OBJ_STOP_ITERATION; } + MP_THREAD_GIL_ENTER(); const char *fn = dirent->d_name; if (fn[0] == '.' && (fn[1] == 0 || fn[1] == '.')) { @@ -229,7 +233,9 @@ STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) { if (path[0] == '\0') { path = "."; } + MP_THREAD_GIL_EXIT(); iter->dir = opendir(path); + MP_THREAD_GIL_ENTER(); if (iter->dir == NULL) { mp_raise_OSError(errno); } @@ -245,7 +251,10 @@ typedef struct _mp_obj_listdir_t { STATIC mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); - int ret = mkdir(vfs_posix_get_path_str(self, path_in), 0777); + const char *path = vfs_posix_get_path_str(self, path_in); + MP_THREAD_GIL_EXIT(); + int ret = mkdir(path, 0777); + MP_THREAD_GIL_ENTER(); if (ret != 0) { mp_raise_OSError(errno); } @@ -262,7 +271,9 @@ STATIC mp_obj_t vfs_posix_rename(mp_obj_t self_in, mp_obj_t old_path_in, mp_obj_ mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); const char *old_path = vfs_posix_get_path_str(self, old_path_in); const char *new_path = vfs_posix_get_path_str(self, new_path_in); + MP_THREAD_GIL_EXIT(); int ret = rename(old_path, new_path); + MP_THREAD_GIL_ENTER(); if (ret != 0) { mp_raise_OSError(errno); } @@ -278,7 +289,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_rmdir_obj, vfs_posix_rmdir); STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); struct stat sb; - int ret = stat(vfs_posix_get_path_str(self, path_in), &sb); + const char *path = vfs_posix_get_path_str(self, path_in); + MP_THREAD_GIL_EXIT(); + int ret = stat(path, &sb); + MP_THREAD_GIL_ENTER(); if (ret != 0) { mp_raise_OSError(errno); } @@ -321,7 +335,9 @@ STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); STRUCT_STATVFS sb; const char *path = vfs_posix_get_path_str(self, path_in); + MP_THREAD_GIL_EXIT(); int ret = STATVFS(path, &sb); + MP_THREAD_GIL_ENTER(); if (ret != 0) { mp_raise_OSError(errno); } diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 87c202e3b0..c817e51b8b 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include "py/mpthread.h" #include "py/runtime.h" #include "py/stream.h" #include "extmod/vfs_posix.h" @@ -100,7 +101,9 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ } const char *fname = mp_obj_str_get_str(fid); + MP_THREAD_GIL_EXIT(); int fd = open(fname, mode_x | mode_rw, 0644); + MP_THREAD_GIL_ENTER(); if (fd == -1) { mp_raise_OSError(errno); } @@ -135,7 +138,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(vfs_posix_file___exit___obj, 4, 4, vf STATIC mp_uint_t vfs_posix_file_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { mp_obj_vfs_posix_file_t *o = MP_OBJ_TO_PTR(o_in); check_fd_is_open(o); + MP_THREAD_GIL_EXIT(); mp_int_t r = read(o->fd, buf, size); + MP_THREAD_GIL_ENTER(); if (r == -1) { *errcode = errno; return MP_STREAM_ERROR; @@ -159,7 +164,9 @@ STATIC mp_uint_t vfs_posix_file_write(mp_obj_t o_in, const void *buf, mp_uint_t MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; nlr_raise(obj); } + MP_THREAD_GIL_EXIT(); r = write(o->fd, buf, size); + MP_THREAD_GIL_ENTER(); } if (r == -1) { *errcode = errno; @@ -173,14 +180,19 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_ check_fd_is_open(o); switch (request) { case MP_STREAM_FLUSH: - if (fsync(o->fd) < 0) { + MP_THREAD_GIL_EXIT(); + int ret = fsync(o->fd); + MP_THREAD_GIL_ENTER(); + if (ret == -1) { *errcode = errno; return MP_STREAM_ERROR; } return 0; case MP_STREAM_SEEK: { struct mp_stream_seek_t *s = (struct mp_stream_seek_t*)arg; + MP_THREAD_GIL_EXIT(); off_t off = lseek(o->fd, s->offset, s->whence); + MP_THREAD_GIL_ENTER(); if (off == (off_t)-1) { *errcode = errno; return MP_STREAM_ERROR; @@ -189,7 +201,9 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_ return 0; } case MP_STREAM_CLOSE: + MP_THREAD_GIL_EXIT(); close(o->fd); + MP_THREAD_GIL_ENTER(); #ifdef MICROPY_CPYTHON_COMPAT o->fd = -1; #endif