summaryrefslogtreecommitdiff
path: root/extmod/modlwip.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/modlwip.c')
-rw-r--r--extmod/modlwip.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 6960546f6..d501f4be2 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -859,15 +859,28 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_listen_obj, lwip_socket_listen);
STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(self_in);
- if (socket->pcb.tcp == NULL) {
- mp_raise_OSError(MP_EBADF);
- }
if (socket->type != MOD_NETWORK_SOCK_STREAM) {
mp_raise_OSError(MP_EOPNOTSUPP);
}
+
+ // Create new socket object, do it here because we must not raise an out-of-memory
+ // exception when the LWIP concurrency lock is held
+ lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t);
+ socket2->base.type = &lwip_socket_type;
+
+ MICROPY_PY_LWIP_ENTER
+
+ if (socket->pcb.tcp == NULL) {
+ MICROPY_PY_LWIP_EXIT
+ m_del_obj(lwip_socket_obj_t, socket2);
+ mp_raise_OSError(MP_EBADF);
+ }
+
// I need to do this because "tcp_accepted", later, is a macro.
struct tcp_pcb *listener = socket->pcb.tcp;
if (listener->state != LISTEN) {
+ MICROPY_PY_LWIP_EXIT
+ m_del_obj(lwip_socket_obj_t, socket2);
mp_raise_OSError(MP_EINVAL);
}
@@ -875,26 +888,29 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget];
if (*incoming_connection == NULL) {
if (socket->timeout == 0) {
+ MICROPY_PY_LWIP_EXIT
+ m_del_obj(lwip_socket_obj_t, socket2);
mp_raise_OSError(MP_EAGAIN);
} else if (socket->timeout != -1) {
- for (mp_uint_t retries = socket->timeout / 100; retries--;) {
+ mp_uint_t retries = socket->timeout / 100;
+ while (*incoming_connection == NULL) {
+ MICROPY_PY_LWIP_EXIT
+ if (retries-- == 0) {
+ m_del_obj(lwip_socket_obj_t, socket2);
+ mp_raise_OSError(MP_ETIMEDOUT);
+ }
mp_hal_delay_ms(100);
- if (*incoming_connection != NULL) break;
- }
- if (*incoming_connection == NULL) {
- mp_raise_OSError(MP_ETIMEDOUT);
+ MICROPY_PY_LWIP_REENTER
}
} else {
while (*incoming_connection == NULL) {
+ MICROPY_PY_LWIP_EXIT
poll_sockets();
+ MICROPY_PY_LWIP_REENTER
}
}
}
- // create new socket object
- lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t);
- socket2->base.type = &lwip_socket_type;
-
// We get a new pcb handle...
socket2->pcb.tcp = *incoming_connection;
if (++socket->incoming.connection.iget >= socket->incoming.connection.alloc) {
@@ -916,6 +932,8 @@ STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
tcp_accepted(listener);
+ MICROPY_PY_LWIP_EXIT
+
// make the return value
uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE];
memcpy(ip, &(socket2->pcb.tcp->remote_ip), sizeof(ip));