diff options
author | David Lechner <david@pybricks.com> | 2020-01-22 23:54:38 -0600 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2020-03-27 14:40:46 +1100 |
commit | 9418611c8aa860812e28b6e2b6bfde7be5817b43 (patch) | |
tree | 5e42c1510ea143c8b279641dbae5e1b178edf5b4 /extmod/vfs_posix.c | |
parent | 5e6cee07aba4fd73c13024f091a287171bea1f17 (diff) |
unix: Implement PEP 475 to retry syscalls failing with EINTR.
https://www.python.org/dev/peps/pep-0475/
This implements something similar to PEP 475 on the unix port, and for the
VfsPosix class.
There are a few differences from the CPython implementation:
- Since we call mp_handle_pending() between any ENITR's, additional
functions could be called if MICROPY_ENABLE_SCHEDULER is enabled, not
just signal handlers.
- CPython only handles signal on the main thread, so other threads will
raise InterruptedError instead of retrying. On MicroPython,
mp_handle_pending() will currently raise exceptions on any thread.
A new macro MP_HAL_RETRY_SYSCALL is introduced to reduce duplicated code
and ensure that all instances behave the same. This will also allow other
ports that use POSIX-like system calls (and use, eg, VfsPosix) to provide
their own implementation if needed.
Diffstat (limited to 'extmod/vfs_posix.c')
-rw-r--r-- | extmod/vfs_posix.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 55a3e71d1..f14f56e81 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/mphal.h" #include "py/mpthread.h" #include "extmod/vfs.h" #include "extmod/vfs_posix.h" @@ -290,12 +291,8 @@ 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; 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); - } + int ret; + MP_HAL_RETRY_SYSCALL(ret, stat(path, &sb), mp_raise_OSError(err)); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.st_mode); t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.st_ino); @@ -335,12 +332,8 @@ 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); - } + int ret; + MP_HAL_RETRY_SYSCALL(ret, STATVFS(path, &sb), mp_raise_OSError(err)); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.f_bsize); t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.f_frsize); |