Skip to content

Commit afce978

Browse files
committed
extmod/modlwip: Rework how Python accept callback is called.
Calling it from lwIP accept callback will lead incorrect functioning and/or packet leaks if Python callback has any networking calls, due to lwIP non-reentrancy. So, instead schedule "poll" callback to do that, which will be called by lwIP when it does not perform networking activities. "Poll" callback is called infrequently though (docs say every 0.5s by default), so for better performance, lwIP needs to be patched to call poll callback soon after accept callback, but when current packet is already processed.
1 parent ca63c77 commit afce978

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

extmod/modlwip.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,17 @@ STATIC err_t _lwip_tcp_recv_unaccepted(void *arg, struct tcp_pcb *pcb, struct pb
311311
return ERR_BUF;
312312
}
313313

314+
// "Poll" (idle) callback to be called ASAP after accept callback
315+
// to execute Python callback function, as it can't be executed
316+
// from accept callback itself.
317+
STATIC err_t _lwip_tcp_accept_finished(void *arg, struct tcp_pcb *pcb)
318+
{
319+
lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg;
320+
tcp_poll(pcb, NULL, 0);
321+
exec_user_callback(socket);
322+
return ERR_OK;
323+
}
324+
314325
// Callback for incoming tcp connections.
315326
STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
316327
lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg;
@@ -323,7 +334,12 @@ STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
323334
return ERR_BUF;
324335
} else {
325336
socket->incoming.connection = newpcb;
326-
exec_user_callback(socket);
337+
if (socket->callback != MP_OBJ_NULL) {
338+
// Schedule accept callback to be called when lwIP is done
339+
// with processing this incoming connection on its side and
340+
// is idle.
341+
tcp_poll(newpcb, _lwip_tcp_accept_finished, 1);
342+
}
327343
return ERR_OK;
328344
}
329345
}

0 commit comments

Comments
 (0)