net_sendfile: Let the ACK callback handle the REXMIT flag and don't return until all data has been ACK'd. From Max Holtzberg

This commit is contained in:
Gregory Nutt 2013-10-17 09:54:48 -06:00
parent 8ca54913e2
commit b38468d49f
2 changed files with 30 additions and 23 deletions

View File

@ -5787,5 +5787,7 @@
Max Holtzberg (2013-10-17).
* net/uip/uip_tcpinput.c: Move tcp connection into SYN_RCVD state
after aception instead of bypassing and moving directly into ESTABLISHED.
From Max Holtzber (2013-10-17).
From Max Holtzberg (2013-10-17).
* net/net_sendfile.c: Let the ACK callback handle the REXMIT flag and
don't return until all data has been ACK'd. From Max Holtzberg
(2013-10-17).

View File

@ -170,12 +170,18 @@ static uint16_t ack_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
dev->d_sndlen = 0;
/* Wake up the waiting thread */
sem_post(&pstate->snd_sem);
flags &= ~UIP_ACKDATA;
}
else if ((flags & UIP_REXMIT) != 0)
{
nlldbg("REXMIT\n");
/* Yes.. in this case, reset the number of bytes that have been sent
* to the number of bytes that have been ACKed.
*/
pstate->snd_sent = pstate->snd_acked;
}
/* Check for a loss of connection */
@ -187,10 +193,12 @@ static uint16_t ack_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
net_lostconnection(pstate->snd_sock, flags);
pstate->snd_sent = -ENOTCONN;
sem_post(&pstate->snd_sem);
}
/* Wake up the waiting thread */
sem_post(&pstate->snd_sem);
return flags;
}
@ -224,20 +232,9 @@ static uint16_t sendfile_interrupt(FAR struct uip_driver_s *dev, FAR void *pvcon
nllvdbg("flags: %04x acked: %d sent: %d\n",
flags, pstate->snd_acked, pstate->snd_sent);
if ((flags & UIP_REXMIT) != 0)
{
/* Yes.. in this case, reset the number of bytes that have been sent
* to the number of bytes that have been ACKed.
*/
pstate->snd_sent = pstate->snd_acked;
/* Fall through to re-send data from the last that was ACKed */
}
/* Check for a loss of connection */
else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
/* Report not connected */
@ -356,6 +353,14 @@ static uint16_t sendfile_interrupt(FAR struct uip_driver_s *dev, FAR void *pvcon
}
#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
if (pstate->snd_sent >= pstate->snd_flen
&& pstate->snd_acked < pstate->snd_flen)
{
/* All data has been sent, but there are outstanding ACK's */
goto wait;
}
end_wait:
/* Do not allow any further callbacks */
@ -521,7 +526,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
/* Set up the ACK callback in the connection */
state.snd_ackcb->flags = UIP_ACKDATA|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
state.snd_ackcb->flags = UIP_ACKDATA|UIP_REXMIT|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
state.snd_ackcb->priv = (void*)&state;
state.snd_ackcb->event = ack_interrupt;
@ -529,7 +534,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
do
{
state.snd_datacb->flags = UIP_REXMIT|UIP_POLL;
state.snd_datacb->flags = UIP_POLL;
state.snd_datacb->priv = (void*)&state;
state.snd_datacb->event = sendfile_interrupt;
@ -539,7 +544,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
uip_lockedwait(&state.snd_sem);
}
while (state.snd_sent > 0 && state.snd_acked < state.snd_flen);
while (state.snd_sent >= 0 && state.snd_acked < state.snd_flen);
/* Set the socket state to idle */