[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lwip-users] pbuf question
From: |
Leon Woestenberg |
Subject: |
Re: [lwip-users] pbuf question |
Date: |
Sun, 11 Jul 2004 02:55:59 +0200 |
User-agent: |
Mozilla Thunderbird 0.7.1 (Windows/20040626) |
Hello Tim,
please read pbuf.c function inline documentation and also pbuf.h
structure inline documentation.
I think what you need is the pbuf_cat() function.
But to lay down some understanding:
The "ref" counter counts how many pointer references there are to that pbuf.
given
(pbuf1->ref, pbuf1->next->ref) = (1,1)
(pbuf2->ref, pbuf2->next->ref) = (1,1)
and then calling pbuf_chain(pbuf1, pbuf2) will indeed result in
(pbuf1->ref, pbuf1->next->ref, pbuf1->next->next->ref,
pbuf1->next->next->next->ref) = (1,1,2,1)
as lwIP thinks there is one pointer to the first pbuf (namely "pbuf1"),
one pointer to the second pbuf
(namely "pbuf1->next"), two pointers to the third pbuf (namely
"pbuf1->next->next" and "pbuf2")
and one pointer to the fourth pbuf (namely "pbuf1->next->next->next").
When your application chains the two pbufs, and releases its pointer
reference to the second, it
should call pbuf_free(pbuf2) to inform lwIP on the released pointer,
just like Jim Gibbons deduced
and described correctly (see below). But pbuf_cat() is more optimal in
that case.
pbuf_cat(pbuf1, pbuf2) explicitly assumes that you release the pbuf2
pointer (i.e. no longer use it).
BTW, to easen debugging, you should really do a pbuf2 = NULL; right
after your call to pbuf_cat(...,pbuf2)
or pbuf_free(pbuf2).
Jim Gibbons wrote:
If you look in tcp_in.c, in tcp_receive, you will find a call to
pbuf_chain that seems analogous to yours. It is followed by a call to
pbuf_free, which undoes the ref increment in pbuf_chain. In fact,
when I scanned the code in core, I found that every pbuf_chain call
was followed immediately by a pbuf_free. I have to agree that this
situation does make it seem that perhaps the operations of the pbuf
chain and queue functions aren't as convenient to the caller as they
might be.
In defense of the way things are, however, the caller of pbuf_chain is
still in possession of both of the pbuf pointers upon return. It
isn't clear (to pbuf_chain) whether the caller will abandon the one
that has been attached to the chain or continue to use it. The
pbuf_free call after pbuf_chain makes this clear, though perhaps at
the cost of efficiency.
Side-note about "the slight cost of efficiency": This was discussed on
the lwip-devel list earlier, but we really
needed an orthogonal pbuf_chain() and pbuf_free() for some
implementation reason I do not recall at this
point.
pbuf_cat() is optimal
pbuf_chain() is just a pbuf_cat(); pbuf_ref().
pbuf_chain(); pbuf_free() is equal to pbuf_cat(); pbuf_ref(); pbuf_free()
pbuf_ref(); pbuf_free() is the unwanted overhead (which is a no-op).
Regards,
Leon.