IOB: Need to clone header when deleting the first entry in an I/O buffer chain

This commit is contained in:
Gregory Nutt 2014-06-05 11:19:00 -06:00
parent 3881bf6b5f
commit c92645017b
2 changed files with 41 additions and 4 deletions

View File

@ -40,6 +40,7 @@
#include <nuttx/config.h>
#include <queue.h>
#include <assert.h>
#include <nuttx/net/iob.h>
@ -76,8 +77,40 @@
FAR struct iob_s *iob_free(FAR struct iob_s *iob)
{
sq_entry_t *next = iob->io_link.flink;
FAR struct iob_s *next = (FAR struct iob_s *)iob->io_link.flink;
/* Copy the data that only exists in the head of a I/O buffer chain into
* the next entry.
*/
if (next)
{
/* Just copy the flags and private information */
next->io_flags = iob->io_flags;
next->io_priv = iob->io_priv;
/* Copy and decrement the total packet length, being careful to
* do nothing too crazy.
*/
if (iob->io_pktlen > iob->io_len)
{
next->io_pktlen = iob->io_pktlen - iob->io_len;
DEBUGASSERT(next->io_pktlen >= next->io_len);
}
else
{
next->io_pktlen = 0;
DEBUGASSERT(next->io_pktlen == 0 && next->io_link.flink == NULL);
}
}
/* Free the I/O buffer by adding to the end of the free list */
sq_addlast(&iob->io_link, &g_iob_freelist);
return (FAR struct iob_s *)next;
/* And return the I/O buffer after the one that was freed */
return next;
}

View File

@ -75,8 +75,8 @@
void iob_freeq(FAR sq_queue_t *q)
{
/* If the free list is empty, then just move the entry queue to the the
* free list. Otherwise, append the list to the end of the free list.
/* If the free list is empty, then just move the entry queue to the free
* list. Otherwise, append the list to the end of the free list.
*/
if (g_iob_freelist.tail)
@ -93,4 +93,8 @@ void iob_freeq(FAR sq_queue_t *q)
*/
g_iob_freelist.tail = q->tail;
/* Reset the queue to empty */
sq_init(q);
}