lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Freeing memory after http transfer


From: Bernhard 'Gustl' Bauer
Subject: Re: [lwip-users] Freeing memory after http transfer
Date: Fri, 13 Nov 2009 12:35:14 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

address@hidden schrieb:
Bernhard,
I'm currently (though very infrequently) in the process of working on httpd, so I'm not really sure on which version you are based.

I'm based on lwip 1.3.0


However, there are two correct ways when to free application buffers:
- when data is copied with tcp_write(), application data can be freed when tcp_write() returns ERR_OK since then data is bufferd internally (this is left == 0) - when data is *not* copied with tcp_write(), these buffers must stay unchanged until the data is actually ACKed (i.e. will not be sent again by lwIP tcp). This is the case when the number of bytes acked (the len argument of http_sent()) equals the size of data you wrote.

Since the httpd in contrib tells tcp_write() to copy data to internal buffers, the version of http_sent below is OK.

tcp_write is used in my copy too. And I see your point. But whenever I use the original http_sent the data in the last packet is cleared. I just verified it again.

Instead of clearing the memory I just filled it with its addresses. The addresses are not in the buffers of the LWIP, so I do not accidentally clear the wrong buffers :-)

This is my memcpy:
void pmemcpy(void *dst, void *src, unsigned int len) {
  unsigned int i;
        
  for (i=0;(i+8)<=len;i+=8) {
    memcpy((void *)((unsigned int)dst+i),(void *)((unsigned int)src+i),8);
  }
  if (i<len) {
memcpy((void *)((unsigned int)dst+i),(void *)((unsigned int)src+i),len-i);
  }
}
It is split up to give IRQs a chance.

So it looks still as if the memory is used until the last packed is ackowledged.



Simon


Bernhard 'Gustl' Bauer wrote:
Kieran Mansley schrieb:
Each time tcp_sent is called it tells you how much data has been
released.  Keep a count of this.  When your count equals the size of
data you sent, you know it's all done.

This is the original http_sent:

static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) {
   struct http_state *hs;

   LWIP_UNUSED_ARG(len);
   hs = arg;
   hs->retries = 0;

   if (hs->left > 0) {
     send_data(pcb, hs);
   } else {
     close_conn(pcb, hs);
   }
   return ERR_OK;
}

If hs->left == 0 this does not mean that all data has already been sent out. The last packet is just somewere in the pipeline. So the connection cannot be closed yet.

I can remember something puzzled my when doing the first steps: Used buffers where freed by a function called from the timers. Probably this was the cause.

I would suggest to add bytes_to_send and bytes_acked to struct http_state and to change the function like this:

static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) {
   struct http_state *hs;

   LWIP_UNUSED_ARG(len);
   hs = arg;
   hs->retries = 0;
   hs->bytes_acked+=len;
if (hs->left > 0) {
     send_data(pcb, hs);
   }
   if (hs->bytes_acked==hs->bytes_to_send) {
     close_conn(pcb, hs);
   }
   return ERR_OK;
}



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users




_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users





reply via email to

[Prev in Thread] Current Thread [Next in Thread]