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:
parent
8ca54913e2
commit
b38468d49f
@ -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).
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user