@@ -491,6 +491,7 @@ bool sockinfo_tcp::prepare_to_close(bool process_shutdown /* = false */)
491491 tcp_accept (&m_pcb, 0 );
492492 tcp_syn_handled ((struct tcp_pcb_listen *)(&m_pcb), 0 );
493493 tcp_clone_conn ((struct tcp_pcb_listen *)(&m_pcb), 0 );
494+ tcp_accepted_pcb ((struct tcp_pcb_listen *)(&m_pcb), 0 );
494495 prepare_listen_to_close (); // close pending to accept sockets
495496 } else {
496497 tcp_recv (&m_pcb, sockinfo_tcp::rx_drop_lwip_cb);
@@ -2452,7 +2453,7 @@ int sockinfo_tcp::listen(int backlog)
24522453 tcp_accept (&m_pcb, sockinfo_tcp::accept_lwip_cb);
24532454 tcp_syn_handled ((struct tcp_pcb_listen *)(&m_pcb), sockinfo_tcp::syn_received_lwip_cb);
24542455 tcp_clone_conn ((struct tcp_pcb_listen *)(&m_pcb), sockinfo_tcp::clone_conn_cb);
2455-
2456+ tcp_accepted_pcb (( struct tcp_pcb_listen *)(&m_pcb), sockinfo_tcp::accepted_pcb_cb);
24562457 bool success = attach_as_uc_receiver (ROLE_TCP_SERVER);
24572458
24582459 if (!success) {
@@ -2699,6 +2700,11 @@ sockinfo_tcp *sockinfo_tcp::accept_clone()
26992700 return 0 ;
27002701 }
27012702
2703+ // This method is called from a flow which assumes that the socket is locked
2704+ // (tcp_listen_input, L3_level_tcp_input).
2705+ // Since we created a new socket and we are about to add it to the timers,
2706+ // we need to make sure it is also locked for further processing.
2707+ si->lock_tcp_con ();
27022708 si->m_parent = this ;
27032709
27042710 si->m_sock_state = TCP_SOCK_BOUND;
@@ -2943,6 +2949,15 @@ err_t sockinfo_tcp::clone_conn_cb(void *arg, struct tcp_pcb **newpcb, err_t err)
29432949 return ret_val;
29442950}
29452951
2952+ void sockinfo_tcp::accepted_pcb_cb (struct tcp_pcb *accepted_pcb)
2953+ {
2954+ // A new pcb is always locked. When this callback is called the new pcb is ready
2955+ // and all related processing is done. Now it must be unlocked.
2956+ sockinfo_tcp *accepted_sock = reinterpret_cast <sockinfo_tcp *>(accepted_pcb->my_container );
2957+ ASSERT_LOCKED (accepted_sock->m_tcp_con_lock );
2958+ accepted_sock->unlock_tcp_con ();
2959+ }
2960+
29462961err_t sockinfo_tcp::syn_received_lwip_cb (void *arg, struct tcp_pcb *newpcb, err_t err)
29472962{
29482963 sockinfo_tcp *listen_sock = (sockinfo_tcp *)((arg));
@@ -2978,6 +2993,10 @@ err_t sockinfo_tcp::syn_received_lwip_cb(void *arg, struct tcp_pcb *newpcb, err_
29782993 if (!is_new_offloaded) {
29792994 new_sock->setPassthrough ();
29802995 set_tcp_state (&new_sock->m_pcb , CLOSED);
2996+ // This method is called from a flow (tcp_listen_input, L3_level_tcp_input) which priorly
2997+ // called clone_conn_cb which creates a locked new socket. Before we call to close() we need
2998+ // to unlock the socket, so close() can perform as a regular close() call.
2999+ new_sock->unlock_tcp_con ();
29813000 close (new_sock->get_fd ());
29823001 listen_sock->m_tcp_con_lock .lock ();
29833002 return ERR_ABRT;
@@ -3019,6 +3038,11 @@ err_t sockinfo_tcp::syn_received_drop_lwip_cb(void *arg, struct tcp_pcb *newpcb,
30193038 tcp_arg (&(new_sock->m_pcb ), new_sock);
30203039 new_sock->abort_connection ();
30213040 }
3041+ // This method is called from a flow (tcp_listen_input, L3_level_tcp_input) which priorly called
3042+ // clone_conn_cb which creates a locked new socket. Before we call to close() we need to unlock
3043+ // the socket, so close() can perform as a regular close() call.
3044+ new_sock->unlock_tcp_con ();
3045+
30223046 close (new_sock->get_fd ());
30233047
30243048 listen_sock->m_tcp_con_lock .lock ();
0 commit comments