2006-02-07 00:25:02 +10:00
/** \file halloc.c
2006-02-07 04:11:01 +10:00
A hierarchical memory allocation system . Works just like talloc
used in Samba , except that an arbitrary block allocated with
malloc ( ) can be registered to be freed by halloc_free .
2006-02-07 00:25:02 +10:00
*/
# include "config.h"
# include <stdlib.h>
# include <unistd.h>
# include "util.h"
# include "common.h"
# include "halloc.h"
typedef struct halloc
{
array_list_t children ;
long long data [ 0 ] ;
}
halloc_t ;
static halloc_t * halloc_from_data ( void * data )
{
return ( halloc_t * ) ( data - sizeof ( halloc_t ) ) ;
}
void * halloc ( void * context , size_t size )
2006-02-10 01:50:20 +10:00
{
2006-02-07 04:11:01 +10:00
halloc_t * me , * parent ;
2006-02-07 00:25:02 +10:00
2006-02-07 04:11:01 +10:00
me = ( halloc_t * ) calloc ( 1 , sizeof ( halloc_t ) + size ) ;
2006-02-10 01:50:20 +10:00
2006-02-07 04:11:01 +10:00
if ( ! me )
return 0 ;
2006-02-10 01:50:20 +10:00
2006-02-07 04:11:01 +10:00
al_init ( & me - > children ) ;
2006-02-10 01:50:20 +10:00
2006-02-07 00:25:02 +10:00
if ( context )
2006-02-07 04:11:01 +10:00
{
parent = halloc_from_data ( context ) ;
2006-02-10 01:50:20 +10:00
al_push ( & parent - > children , & halloc_free ) ;
al_push ( & parent - > children , & me - > data ) ;
2006-02-07 00:25:02 +10:00
}
2006-02-10 01:50:20 +10:00
2006-02-07 04:11:01 +10:00
return & me - > data ;
2006-02-07 00:25:02 +10:00
}
2006-02-10 01:50:20 +10:00
void halloc_register_function ( void * context , void ( * func ) ( void * ) , void * data )
2006-02-07 00:25:02 +10:00
{
halloc_t * me ;
if ( ! context )
2006-02-10 01:50:20 +10:00
return ;
2006-02-07 00:25:02 +10:00
me = halloc_from_data ( context ) ;
2006-02-10 01:50:20 +10:00
al_push ( & me - > children , func ) ;
2006-02-07 04:11:01 +10:00
al_push ( & me - > children , data ) ;
2006-02-07 00:25:02 +10:00
}
2006-02-07 04:11:01 +10:00
void halloc_free ( void * context )
2006-02-07 00:25:02 +10:00
{
2006-02-07 04:11:01 +10:00
halloc_t * me ;
2006-02-10 01:50:20 +10:00
int i ;
2006-02-07 04:11:01 +10:00
if ( ! context )
return ;
2006-02-10 01:50:20 +10:00
2006-02-07 04:11:01 +10:00
me = halloc_from_data ( context ) ;
2006-02-10 01:50:20 +10:00
for ( i = 0 ; i < al_get_count ( & me - > children ) ; i + = 2 )
{
void ( * func ) ( void * ) = ( void ( * ) ( void * ) ) al_get ( & me - > children , i ) ;
void * data = ( void * ) al_get ( & me - > children , i + 1 ) ;
func ( data ) ;
}
2006-02-07 04:11:01 +10:00
al_destroy ( & me - > children ) ;
free ( me ) ;
2006-02-07 00:25:02 +10:00
}