657 |
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t)); |
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t)); |
658 |
} |
} |
659 |
|
|
660 |
/** |
|
|
* Dechains the first pbuf from its succeeding pbufs in the chain. |
|
|
* |
|
|
* Makes p->tot_len field equal to p->len. |
|
|
* @param p pbuf to dechain |
|
|
* @return remainder of the pbuf chain, or NULL if it was de-allocated. |
|
|
*/ |
|
|
struct pbuf * |
|
|
pbuf_dechain(struct pbuf *p) |
|
|
{ |
|
|
struct pbuf *q; |
|
|
u8_t tail_gone = 1; |
|
|
/* tail */ |
|
|
q = p->next; |
|
|
/* pbuf has successor in chain? */ |
|
|
if (q != NULL) { |
|
|
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |
|
|
LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); |
|
|
/* enforce invariant if assertion is disabled */ |
|
|
q->tot_len = p->tot_len - p->len; |
|
|
/* decouple pbuf from remainder */ |
|
|
p->next = NULL; |
|
|
/* total length of pbuf p is its own length only */ |
|
|
p->tot_len = p->len; |
|
|
/* q is no longer referenced by p, free it */ |
|
|
DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q)); |
|
|
tail_gone = pbuf_free(q); |
|
|
/* return remaining tail or NULL if deallocated */ |
|
|
} |
|
|
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |
|
|
LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); |
|
|
return (tail_gone > 0? NULL: q); |
|
|
} |
|
661 |
|
|
662 |
/** |
/** |
663 |
* |
* |
763 |
return head; |
return head; |
764 |
} |
} |
765 |
|
|
766 |
|
#if 0 /* expected to enabled again, once needed (multiple chain queueing comes to mind) */ |
767 |
|
/** |
768 |
|
* Dechains the first pbuf from its succeeding pbufs in the chain. |
769 |
|
* |
770 |
|
* Makes p->tot_len field equal to p->len. |
771 |
|
* @param p pbuf to dechain |
772 |
|
* @return remainder of the pbuf chain, or NULL if it was de-allocated. |
773 |
|
*/ |
774 |
|
struct pbuf * |
775 |
|
pbuf_dechain(struct pbuf *p) |
776 |
|
{ |
777 |
|
struct pbuf *q; |
778 |
|
u8_t tail_gone = 1; |
779 |
|
/* tail */ |
780 |
|
q = p->next; |
781 |
|
/* pbuf has successor in chain? */ |
782 |
|
if (q != NULL) { |
783 |
|
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |
784 |
|
LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); |
785 |
|
/* enforce invariant if assertion is disabled */ |
786 |
|
q->tot_len = p->tot_len - p->len; |
787 |
|
/* decouple pbuf from remainder */ |
788 |
|
p->next = NULL; |
789 |
|
/* total length of pbuf p is its own length only */ |
790 |
|
p->tot_len = p->len; |
791 |
|
/* q is no longer referenced by p, free it */ |
792 |
|
DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q)); |
793 |
|
tail_gone = pbuf_free(q); |
794 |
|
/* return remaining tail or NULL if deallocated */ |
795 |
|
} |
796 |
|
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |
797 |
|
LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); |
798 |
|
return (tail_gone > 0? NULL: q); |
799 |
|
} |
800 |
|
#endif /* pbuf_dechain() */ |