celix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pepijn Noltes <pepijnnol...@gmail.com>
Subject Re: [Native-OSGi] OSGi API: Allocated memory ownership
Date Mon, 04 Jun 2012 18:25:10 GMT
On Mon, Jun 4, 2012 at 12:00 PM, Alexander Broekhuis
<a.broekhuis@gmail.com> wrote:
> Hi
>
>
>> 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.
>
>>
>> For memory owned by the framework, any memory management technique which
>> guarantees the stated lifetime will do (e.g. APR memory pools).
>>
>
> Since this is "internal" to the framework this can be anything the
> framework implementation uses. For Celix this is indeed APR.
>
> 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...

It does :), but IMO supplying handles - even on framework level - is
not a good idea. It will add too much complexity for something where
most C programmers just expect to use of malloc and free.
Personally I am in favor for using memory pools, but for a generic API
I think we should keep close to "pure" C and in this case use malloc
and let the users call free.

>
> [1]: http://marc.info/?l=apr-dev&m=109065999530290&w=2
>
> --
> Met vriendelijke groet,
>
> Alexander Broekhuis

Mime
View raw message