Wed 12 Sep 2007 01:31:57 PM UTC, original submission:
From discussion of task #6735, it was decided that it should be possible to reuse pbufs after return from API calls.
At present this is not guaranteed, and task #6735 would need to be completed to deal with that, as queuing a pbuf would cause problems if the API user could then modify the pbuf. But there are other issues as discussed in the "udp_send" thread on the lwip-users mailing list of 2007-09-11. In there it was observed that udp_send uses pbuf_header on a pbuf passed to it. As a result, when the pbuf is returned, the payload pointer has changed.
If we are to allow reuse of pbufs, then there must be a mechanism to fix this. Instead of fixing it every time in udp_send, which seemed to be a bit of a faff for something uncommon, I proposed a potential API extension which users would be required to call before reusing a pbuf:
int pbuf_reuse(struct pbuf *p, pbuf_layer l)
{
u16_t offset = 0;
switch (l) {
case PBUF_TRANSPORT:
[... same treatment of offset as pbuf_alloc() ... ]
}
switch (p->type) {
case PBUF_POOL:
case PBUF_RAM:
p->payload = LWIP_MEM_ALIGN((void )((u8_t )p + (SIZEOF_STRUCT_PBUF + offset)));
break;
case PBUF_ROM:
case PBUF_REF:
[do something?]
break;
}
The only problem here is that pbuf_header allows use of a negative header offset for PBUF_ROM and PBUF_REF. If that is done there is no way to restore the old value. In fact that's a problem anyway whether we went for adding this new API call, or some other mechanism of restoring the pbuf. However although the stack uses negative header offset when adjusting incoming pbufs, I don't know for definite if it uses negative header offsets for pbufs for transmission. I haven't found any examples yet. Or maybe it's better just to return an error if this is called for PBUF_ROM or PBUF_REF?
I suspect Simon would like this approach because it gives a particularly good place to check that pbuf->ref is 1 before reuse. On the other hand, it's an API change. Kieran decided it should wait until after 1.3.0.
There may be other examples, especially with the raw API, where pbufs are not returned in the same state they were passed in.
|