diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-19 08:31:50 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-19 08:31:50 -0600 |
commit | 0b88617dcc729a6fbff264b2777d01d776be1d5e (patch) | |
tree | c5171d6a49dd456a957ecbd68cc6f01de3e90e86 /nuttx | |
parent | c04481fc6a04c734a1ee4c6ae6fe292f77fa8842 (diff) | |
download | nuttx-0b88617dcc729a6fbff264b2777d01d776be1d5e.tar.gz nuttx-0b88617dcc729a6fbff264b2777d01d776be1d5e.tar.bz2 nuttx-0b88617dcc729a6fbff264b2777d01d776be1d5e.zip |
TCP write buffering: Add buffer allocation check from Max (himax)
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/net/net_send_buffered.c | 75 |
1 files changed, 47 insertions, 28 deletions
diff --git a/nuttx/net/net_send_buffered.c b/nuttx/net/net_send_buffered.c index 60f2a6134..5bf5e77e2 100644 --- a/nuttx/net/net_send_buffered.c +++ b/nuttx/net/net_send_buffered.c @@ -443,7 +443,7 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, int flags) { uip_lock_t save; - size_t completed = 0; + ssize_t completed = 0; int err; int ret = OK; @@ -469,52 +469,71 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, { struct uip_conn *conn = (struct uip_conn*)psock->s_conn; + /* Allocate resources to receive a callback */ + if (!psock->s_sndcb) { psock->s_sndcb = uip_tcpcallbackalloc(conn); + } + + /* Test if the callback has been allocated*/ + + if (!psock->s_sndcb) + { + /* A buffer allocation error occurred */ + completed = -ENOMEM; + } + else + { /* Set up the callback in the connection */ psock->s_sndcb->flags = (UIP_ACKDATA | UIP_REXMIT |UIP_POLL | \ UIP_CLOSE | UIP_ABORT | UIP_TIMEDOUT); psock->s_sndcb->priv = (void*)psock; psock->s_sndcb->event = send_interrupt; - } - /* Allocate resources to receive a callback */ - - while (completed < len) - { - FAR struct uip_wrbuffer_s *segment = uip_tcpwrbuffer_alloc(NULL); - if (segment) + while (completed < len) { - size_t cnt; + FAR struct uip_wrbuffer_s *segment = uip_tcpwrbuffer_alloc(NULL); + if (segment) + { + size_t cnt; - segment->wb_seqno = (unsigned)-1; - segment->wb_nrtx = 0; + segment->wb_seqno = (unsigned)-1; + segment->wb_nrtx = 0; - if (len - completed > CONFIG_NET_TCP_WRITE_BUFSIZE) - { - cnt = CONFIG_NET_TCP_WRITE_BUFSIZE; - } - else - { - cnt = len - completed; - } + if (len - completed > CONFIG_NET_TCP_WRITE_BUFSIZE) + { + cnt = CONFIG_NET_TCP_WRITE_BUFSIZE; + } + else + { + cnt = len - completed; + } - segment->wb_nbytes = cnt; - memcpy(segment->wb_buffer, (char*)buf + completed, cnt); - completed += cnt; + segment->wb_nbytes = cnt; + memcpy(segment->wb_buffer, (char*)buf + completed, cnt); + completed += cnt; - /* send_interrupt() will refer to all the write buffer by - * conn->writebuff - */ + /* send_interrupt() will refer to all the write buffer by + * conn->writebuff + */ + + sq_addlast(&segment->wb_node, &conn->write_q); - sq_addlast(&segment->wb_node, &conn->write_q); + /* Notify the device driver of the availability of TX data */ + + netdev_txnotify(conn->ripaddr); + } - /* Notify the device driver of the availability of TX data */ + /* A buffer allocation error occurred */ - netdev_txnotify(conn->ripaddr); + else + { + completed = -ENOMEM; + break; + } } } } |