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
