[Ur] missunderstanding - or serious memory handling issue?

Adam Chlipala adamc at impredicative.com
Wed Dec 8 09:23:43 EST 2010


Marc Weber wrote:
> Excerpts from Adam Chlipala's message of Wed Dec 08 02:42:45 +0100 2010:
>    
>> Yes, no callback should touch any uw_malloc()ed memory.
>>      
> So what is uw_malloc worth then?
>    

It's meant for use by the Ur/Web program itself, plus cases where FFI 
functions can act a lot like regular Ur code.  Any case where you store 
a value globally (e.g., as the argument to a saved callback) is 
incompatible with what is expressible in Ur/Web, so it has undefined 
semantics.

>    I must ensure that the free handler reading from the memory is called
>    before the handler which is freeing the malloced memory (Is this
>    documented? Don't think so. So I have to assume that the order of
>    calling free handlers in the uw_push_cleanup or
>    uw_register_transactional never changes)

In the code now, cleanup actions are executed in the order they are 
registered, since they are meant to be very localized, with no 
dependencies between them (the compiler itself only uses cleanup actions 
to delete handles to database queries).  Transactional handlers are 
executed in last-in-first-out order, since a later-allocated object 
might refer to another object that will be freed by an 
earlier-registered handler.  I will add this information to the 
documentation, and I could change either order if there are compelling 
reasons.

> alternative implementation which has a minimal heap and allocates
> additional memory blocks when needed:
>    

If you're suggesting special memory management for Ruby objects, that 
would probably be the best long-term solution, but it might not be much 
better than just using malloc().

> Probably I should define a macro which does all the work for me:
>
> #define MY_URWEB_MALLOC(name, type, size) \
>    type * name = malloc(size);             \
>    // might cause trouble if surrounding code is calling uw_pop_cleanup \
>    // uw_push_cleanup(name, free);         \
>    uw_register_transactional(..... name, free);
>    

That looks fine, as long as uw_push_cleanup() stays commented. :)  If 
you are pushing transactional handlers, there's no need to push a 
cleanup action, too.  That would lead to a double-free.



More information about the Ur mailing list