diff options
Diffstat (limited to 'nuttx/net/net_sendfile.c')
-rw-r--r-- | nuttx/net/net_sendfile.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/nuttx/net/net_sendfile.c b/nuttx/net/net_sendfile.c index 2b5f6b211..17189ae0f 100644 --- a/nuttx/net/net_sendfile.c +++ b/nuttx/net/net_sendfile.c @@ -170,11 +170,17 @@ static uint16_t ack_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn, dev->d_sndlen = 0; - /* Wake up the waiting thread */ + flags &= ~UIP_ACKDATA; + } + else if ((flags & UIP_REXMIT) != 0) + { + nlldbg("REXMIT\n"); - sem_post(&pstate->snd_sem); + /* Yes.. in this case, reset the number of bytes that have been sent + * to the number of bytes that have been ACKed. + */ - flags &= ~UIP_ACKDATA; + 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 */ |