void uip_tcpfree(struct uip_conn *conn) { #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 struct uip_readahead_s *readahead; #endif uip_lock_t flags; /* Because g_free_tcp_connections is accessed from user level and interrupt * level, code, it is necessary to keep interrupts disabled during this * operation. */ DEBUGASSERT(conn->crefs == 0); flags = uip_lock(); /* UIP_ALLOCATED means that that the connection is not in the active list * yet. */ if (conn->tcpstateflags != UIP_ALLOCATED) { /* Remove the connection from the active list */ dq_rem(&conn->node, &g_active_tcp_connections); } /* Release any read-ahead buffers attached to the connection */ #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 while ((readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead)) != NULL) { uip_tcpreadaheadrelease(readahead); } #endif /* Remove any backlog attached to this connection */ #ifdef CONFIG_NET_TCPBACKLOG if (conn->backlog) { uip_backlogdestroy(conn); } /* If this connection is, itself, backlogged, then remove it from the * parent connection's backlog list. */ if (conn->blparent) { uip_backlogdelete(conn->blparent, conn); } #endif /* Mark the connection available and put it into the free list */ conn->tcpstateflags = UIP_CLOSED; dq_addlast(&conn->node, &g_free_tcp_connections); uip_unlock(flags); }
static inline void recvfrom_readahead(struct recvfrom_s *pstate) { FAR struct uip_conn *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn; FAR struct uip_readahead_s *readahead; size_t recvlen; /* Check there is any TCP data already buffered in a read-ahead * buffer. */ do { /* Get the read-ahead buffer at the head of the list (if any) */ readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead); if (readahead) { /* We have a new buffer... transfer that buffered data into * the user buffer. * * First, get the length of the data to transfer. */ if (readahead->rh_nbytes > pstate->rf_buflen) { recvlen = pstate->rf_buflen; } else { recvlen = readahead->rh_nbytes; } if (recvlen > 0) { /* Copy the read-ahead data into the user buffer */ memcpy(pstate->rf_buffer, readahead->rh_buffer, recvlen); nllvdbg("Received %d bytes (of %d)\n", recvlen, readahead->rh_nbytes); /* Update the accumulated size of the data read */ pstate->rf_recvlen += recvlen; pstate->rf_buffer += recvlen; pstate->rf_buflen -= recvlen; } /* If the read-ahead buffer is empty, then release it. If not, then * we will have to move the data down and return the buffer to the * front of the list. */ if (recvlen < readahead->rh_nbytes) { readahead->rh_nbytes -= recvlen; memcpy(readahead->rh_buffer, &readahead->rh_buffer[recvlen], readahead->rh_nbytes); sq_addfirst(&readahead->rh_node, &conn->readahead); } else { uip_tcpreadaheadrelease(readahead); } } } while (readahead && pstate->rf_buflen > 0); }