diff options
Diffstat (limited to 'ports/unix/modusocket.c')
-rw-r--r-- | ports/unix/modusocket.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 9b82378bb4..b436ddf7fc 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -45,6 +45,7 @@ #include "py/stream.h" #include "py/builtin.h" #include "py/mphal.h" +#include "py/mpthread.h" /* The idea of this module is to implement reasonable minimum of @@ -93,7 +94,9 @@ STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kin STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { mp_obj_socket_t *o = MP_OBJ_TO_PTR(o_in); + MP_THREAD_GIL_EXIT(); mp_int_t r = read(o->fd, buf, size); + MP_THREAD_GIL_ENTER(); if (r == -1) { int err = errno; // On blocking socket, we get EAGAIN in case SO_RCVTIMEO/SO_SNDTIMEO @@ -110,7 +113,9 @@ STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { mp_obj_socket_t *o = MP_OBJ_TO_PTR(o_in); + MP_THREAD_GIL_EXIT(); mp_int_t r = write(o->fd, buf, size); + MP_THREAD_GIL_ENTER(); if (r == -1) { int err = errno; // On blocking socket, we get EAGAIN in case SO_RCVTIMEO/SO_SNDTIMEO @@ -137,7 +142,9 @@ STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i // The rationale MicroPython follows is that close() just releases // file descriptor. If you're interested to catch I/O errors before // closing fd, fsync() it. + MP_THREAD_GIL_EXIT(); close(self->fd); + MP_THREAD_GIL_ENTER(); return 0; case MP_STREAM_GET_FILENO: @@ -159,7 +166,9 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_socket_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ); + MP_THREAD_GIL_EXIT(); int r = connect(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len); + MP_THREAD_GIL_ENTER(); int err = errno; if (r == -1 && self->blocking && err == EINPROGRESS) { // EINPROGRESS on a blocking socket means the operation timed out @@ -174,7 +183,9 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_socket_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ); + MP_THREAD_GIL_EXIT(); int r = bind(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); return mp_const_none; } @@ -182,7 +193,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { mp_obj_socket_t *self = MP_OBJ_TO_PTR(self_in); + MP_THREAD_GIL_EXIT(); int r = listen(self->fd, MP_OBJ_SMALL_INT_VALUE(backlog_in)); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); return mp_const_none; } @@ -194,7 +207,9 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) { //struct sockaddr_storage addr; byte addr[32]; socklen_t addr_len = sizeof(addr); + MP_THREAD_GIL_EXIT(); int fd = accept(self->fd, (struct sockaddr*)&addr, &addr_len); + MP_THREAD_GIL_ENTER(); int err = errno; if (fd == -1 && self->blocking && err == EAGAIN) { // EAGAIN on a blocking socket means the operation timed out @@ -223,7 +238,9 @@ STATIC mp_obj_t socket_recv(size_t n_args, const mp_obj_t *args) { } byte *buf = m_new(byte, sz); + MP_THREAD_GIL_EXIT(); int out_sz = recv(self->fd, buf, sz, flags); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(out_sz, errno); mp_obj_t ret = mp_obj_new_str_of_type(&mp_type_bytes, buf, out_sz); @@ -245,7 +262,9 @@ STATIC mp_obj_t socket_recvfrom(size_t n_args, const mp_obj_t *args) { socklen_t addr_len = sizeof(addr); byte *buf = m_new(byte, sz); + MP_THREAD_GIL_EXIT(); int out_sz = recvfrom(self->fd, buf, sz, flags, (struct sockaddr*)&addr, &addr_len); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(out_sz, errno); mp_obj_t buf_o = mp_obj_new_str_of_type(&mp_type_bytes, buf, out_sz); @@ -272,7 +291,9 @@ STATIC mp_obj_t socket_send(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + MP_THREAD_GIL_EXIT(); int out_sz = send(self->fd, bufinfo.buf, bufinfo.len, flags); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(out_sz, errno); return MP_OBJ_NEW_SMALL_INT(out_sz); @@ -292,8 +313,10 @@ STATIC mp_obj_t socket_sendto(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo, addr_bi; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(dst_addr, &addr_bi, MP_BUFFER_READ); + MP_THREAD_GIL_EXIT(); int out_sz = sendto(self->fd, bufinfo.buf, bufinfo.len, flags, (struct sockaddr *)addr_bi.buf, addr_bi.len); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(out_sz, errno); return MP_OBJ_NEW_SMALL_INT(out_sz); @@ -319,7 +342,9 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { optval = bufinfo.buf; optlen = bufinfo.len; } + MP_THREAD_GIL_EXIT(); int r = setsockopt(self->fd, level, option, optval, optlen); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); return mp_const_none; } @@ -328,14 +353,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_s STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { mp_obj_socket_t *self = MP_OBJ_TO_PTR(self_in); int val = mp_obj_is_true(flag_in); + MP_THREAD_GIL_EXIT(); int flags = fcntl(self->fd, F_GETFL, 0); - RAISE_ERRNO(flags, errno); + if (flags == -1) { + MP_THREAD_GIL_ENTER(); + RAISE_ERRNO(flags, errno); + } if (val) { flags &= ~O_NONBLOCK; } else { flags |= O_NONBLOCK; } flags = fcntl(self->fd, F_SETFL, flags); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(flags, errno); self->blocking = val; return mp_const_none; @@ -368,9 +398,14 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { if (new_blocking) { int r; + MP_THREAD_GIL_EXIT(); r = setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); - RAISE_ERRNO(r, errno); + if (r == -1) { + MP_THREAD_GIL_ENTER(); + RAISE_ERRNO(r, errno); + } r = setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(r, errno); } @@ -415,7 +450,9 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, siz } } + MP_THREAD_GIL_EXIT(); int fd = socket(family, type, proto); + MP_THREAD_GIL_ENTER(); RAISE_ERRNO(fd, errno); return MP_OBJ_FROM_PTR(socket_new(fd)); } @@ -537,7 +574,9 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { } struct addrinfo *addr_list; + MP_THREAD_GIL_EXIT(); int res = getaddrinfo(host, serv, &hints, &addr_list); + MP_THREAD_GIL_ENTER(); if (res != 0) { // CPython: socket.gaierror |