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.
This commit is contained in:
parent
ca63c77073
commit
afce978aca
|
@ -311,6 +311,17 @@ STATIC err_t _lwip_tcp_recv_unaccepted(void *arg, struct tcp_pcb *pcb, struct pb
|
|||
return ERR_BUF;
|
||||
}
|
||||
|
||||
// "Poll" (idle) callback to be called ASAP after accept callback
|
||||
// to execute Python callback function, as it can't be executed
|
||||
// from accept callback itself.
|
||||
STATIC err_t _lwip_tcp_accept_finished(void *arg, struct tcp_pcb *pcb)
|
||||
{
|
||||
lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg;
|
||||
tcp_poll(pcb, NULL, 0);
|
||||
exec_user_callback(socket);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// Callback for incoming tcp connections.
|
||||
STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
|
||||
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) {
|
|||
return ERR_BUF;
|
||||
} else {
|
||||
socket->incoming.connection = newpcb;
|
||||
exec_user_callback(socket);
|
||||
if (socket->callback != MP_OBJ_NULL) {
|
||||
// Schedule accept callback to be called when lwIP is done
|
||||
// with processing this incoming connection on its side and
|
||||
// is idle.
|
||||
tcp_poll(newpcb, _lwip_tcp_accept_finished, 1);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue