celix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sascha Zelzer <s.zel...@dkfz-heidelberg.de>
Subject Re: [Native-OSGi] OSGi API: Allocated memory ownership
Date Tue, 05 Jun 2012 16:49:01 GMT

On 06/04/2012 12:00 PM, Alexander Broekhuis wrote:
>> I'm not a C - expert, but I think the only viable solution is to
>> accurately document the lifetime and ownership of pointers.
> Well I think this is not a C specific problem, the same applies to C++ I
> guess. Someone has to free allocated memory.
Sure. I meant that I am familiar with a couple of C++ idioms for 
managing memory (smart pointers, copy constructors, implicitly shared 
classes, new/delete overloads, custom allocators etc.) but I am not 
accustomed with possibly existing idioms in C.

>> Memory which is to be owned by the caller (user) could probably be
>> allocated and deleted by using special functions (hooks) provided by each
>> bundle which use implementation specific routines for memory management.
>> Otherwise we just state that the returned memory belongs to the caller.
> This is the more interesting part of the problem.
> How would such hooks look like, and doesn't this making bundles awkward?
> A generic header for this could look like this:
> memory_hooks.h:
>    int mem_alloc(void *handle, size_t size, void **block);
>    int mem_calloc(void *handle, size_t num, size_t size, void **block);
>    int mem_realloc(void *handle, void *block, size_t size, void **newblock);
>    int mem_free(void *handle, void *block);
> These function are basically the "normal" C memory functions, does C++ have
> different/additional ones?
> I've added a *handle to all of them to be able to pass some "instance" to
> it. For example, APR would need a memory pool, which can be a member of the
> instance type/struct.
> How does the framework get the handle? One additional method could work:
> int mem_createHandle(void **handle);
> For APR:
> mem_alloc ->  use apr_palloc(handle->pool, size)
> mem_calloc ->  use apr_pcalloc(handle->pool, size)
> mem_realloc ->  no alternative in APR, implement a solution like [1]
> mem_free ->  not implemented, the user has to clear the pool at some time
> Looking at it like this, I just realize this solution has a huge drawback
> when used in combination with APR. For different calls different pools are
> needed. Using this model, there is only one pool which is used for every
> allocation. Basically this means the user is not in control of the lifetime
> of memory.
> The only solution I can think of is to have the user supply the pool on
> which the memory has to be allocated, but we don't want this on our API.
> A possibility would be to supply the handle (instead of the pool) which is
> used by the memory hooks. For example:
> int bundle_getEntry(bundle, handle, char *name, char **entry)
> Instead of letting the framework use handle, handle is simply passed on the
> the memory hooks and used in a way the caller wants. This also eliminates
> the need for the createHandle function in the header file. The user can
> create one when needed. In case of APR, this handle probably can directly
> be the pool.
> I hope this still makes sense...
> [1]: http://marc.info/?l=apr-dev&m=109065999530290&w=2

Yes, it is getting complicated... ;-)

Maybe another possibility which avoids the introduction of handles in 
the API is to pass the function pointer of the API function being called 
to the memory handling functions. E.g.

int bundle_getEntry(bundle, char *name, char **entry)
   bundle_mem_alloc(bundle_getEntry, <buffer_size>, entry);

So bundles could use different pools for different API calls. Maybe that 
kind of flexibility is enough... If there is no bundle specific 
"mem_alloc" function, the framework could fall back to usual malloc/free 
calls. Does that make sense?

- Sascha

View raw message