libmicrohttpd
[Top][All Lists]
Advanced

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

Re: [libmicrohttpd] request callbacks


From: Eivind Sarto
Subject: Re: [libmicrohttpd] request callbacks
Date: Fri, 4 Jan 2013 19:37:13 -0500

Thanks.  It should be relatively trivial to add a reference count on the object 
I allocate and do what you suggest
and not free it until the last callback has been called.

-eivind
________________________________________
From: address@hidden address@hidden On Behalf Of Christian Grothoff 
address@hidden
Sent: Friday, January 04, 2013 3:49 PM
To: libmicrohttpd development and user mailinglist
Subject: Re: [libmicrohttpd] request callbacks

On 01/05/2013 12:33 AM, Eivind Sarto wrote:
> I am running into problems with my MHD server.  I may be confusing the order 
> of the various callback functions.
> As a result, my server sometimes will sometimes de-reference and allocated 
> structure after it has been freed.
>
> I allocate a private data structure in the default_handler, and free it in 
> the notify_complete handler.
> This generally works fine with most requests.   However, if MHD enforces a 
> connection timeout I will
> get a call to the request MHD_ContentReaderCallback function after the 
> notify_complete has been called.

Well, MHD assumes that response objects and connections are independent,
so it calls the respective functions in (so far) undefined order --
after all, you can share a response among multiple connections.

Now, we can probably change that and force the response reference
counter to be decremented *before* the notify_complete callback, which
should result in a somewhat more predictable sequence of callbacks.

> That means the MHD_ContentReaderCallback function cannot access any data 
> allocated in the default_handler.
> That is why my server sometimes crashes when a connection has been timed out.

Well, it can, if you add a reference counter to organize sharing between
the response callbacks and your notify_complete handler and then NOT
free it if the other part is still using the data.  The problem is that
you are aliasing data (from connection context and response context) and
then get a dangling reference if one of the aliases frees
"unilaterally".  You can avoid this by either giving both parts a copy,
or reference counting, or by trying hard to make sure MHD calls the
callbacks in the right order (for you) everywhere.

> My question is what is the order that these 3 callback functions are called 
> (default_handler, notify_complete, MHD_ContentReaderCallback)
> and if I allocate local data in the default_handler, where do I free it?

Generally, the API says that data you associate with the connection
closure should be freed in the notify_complete handler.  Data you
associate with the response should be freed in the response's
"MHD_ContentReaderFreeCallback".

> Note: I have several different ways to process a request.  Some request use a 
> MHD_ContentReaderCallback and some do not.
> So I cannot free the data allocated in the default_handler in the  
> MHD_ContentReaderCallback.

With reference counting this problem can be solved easily (just don't
increment if you don't use a content reader callback).

Essentially, any aliasing can be problematic (I used to write technical
papers on the "aliasing problem").

Anyway, my suggestion for you is to either duplicate the data (if it is
constant and small) or alias it with reference counting (if it is large
or mutated).  If neither works for you, I think it is conceivable that
we can find all of the places where the response RC is decremented and
move them _before_ the connection's notify_complete handler calls.


Happy hacking!

Christian




reply via email to

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