summaryrefslogtreecommitdiffstatshomepage
path: root/ports/unix/modusocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/unix/modusocket.c')
-rw-r--r--ports/unix/modusocket.c43
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