From 57d53c70e3d1baabbe3207ce0356ca8e38842198 Mon Sep 17 00:00:00 2001 From: axel Date: Tue, 7 Feb 2006 04:11:01 +1000 Subject: [PATCH] Further halloc:ification if fish darcs-hash:20060206181101-ac50b-db0aac307a81e7f0677acd15a9f38ff8c7ff36d2.gz --- Makefile.in | 6 ++--- builtin.c | 56 ++++++++++++++++++++--------------------- common.c | 4 +++ common.h | 4 ++- exec.c | 4 +-- expand.c | 6 ++--- halloc.c | 72 ++++++++++++++++++++++++++--------------------------- halloc.h | 31 +++++++++++++++++------ parser.c | 72 ++++++++--------------------------------------------- proc.c | 30 ---------------------- 10 files changed, 113 insertions(+), 172 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1c516b220..255f016e5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,7 +82,7 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \ # All objects that the system needs to build fish_pager FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \ tokenizer.o input_common.o env_universal.o env_universal_common.o \ - translate.o + translate.o halloc.o # All objects that the system needs to build fish_tests FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \ @@ -90,11 +90,11 @@ FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \ # All objects that the system needs to build fishd FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \ - doc_src/fishd.o + doc_src/fishd.o halloc.o # All objects needed to build mimedb MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \ - xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o + xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o halloc.o # # Files containing documentation for builtins. Should be listed diff --git a/builtin.c b/builtin.c index 7444ef092..b049d3c14 100644 --- a/builtin.c +++ b/builtin.c @@ -406,6 +406,7 @@ static int builtin_block( wchar_t **argv ) { eb->next = block->first_event_block; block->first_event_block = eb; + halloc_register( block, eb ); } else { @@ -917,10 +918,15 @@ static int builtin_function( wchar_t **argv ) int res=0; wchar_t *desc=0; int is_binding=0; - array_list_t *events = al_new(); + array_list_t *events; + int i; woptind=0; + parser_push_block( FUNCTION_DEF ); + events=halloc( current_block, sizeof(array_list_t ) ); + al_init( events ); + const static struct woption long_options[] = { @@ -1003,7 +1009,7 @@ static int builtin_function( wchar_t **argv ) break; } - e = calloc( 1, sizeof(event_t)); + e = halloc( current_block, sizeof(event_t)); if( !e ) die_mem(); e->type = EVENT_SIGNAL; @@ -1027,11 +1033,11 @@ static int builtin_function( wchar_t **argv ) break; } - e = calloc( 1, sizeof(event_t)); + e = halloc( current_block, sizeof(event_t)); if( !e ) die_mem(); e->type = EVENT_VARIABLE; - e->param1.variable = wcsdup( woptarg ); + e->param1.variable = halloc_register( current_block, wcsdup( woptarg )); e->function_name=0; al_push( events, e ); break; @@ -1044,10 +1050,10 @@ static int builtin_function( wchar_t **argv ) wchar_t *end; event_t *e; - e = calloc( 1, sizeof(event_t)); + e = halloc( current_block, sizeof(event_t)); if( !e ) die_mem(); - + if( ( opt == 'j' ) && ( wcscasecmp( woptarg, L"caller" ) == 0 ) ) { @@ -1154,6 +1160,8 @@ static int builtin_function( wchar_t **argv ) } } + halloc_register( current_block, events->arr ); + if( res ) { int i; @@ -1186,33 +1194,27 @@ static int builtin_function( wchar_t **argv ) sb_append2( sb_err, nxt, L" ", (void *)0 ); } - free( names_arr ); + halloc_free( names_arr ); al_destroy( &names ); sb_append( sb_err, L"\n" ); + parser_pop_block(); parser_push_block( FAKE ); - - al_foreach( events, (void (*)(const void *))&event_free ); - al_destroy( events ); - halloc_free( events ); } else { - int i; - - parser_push_block( FUNCTION_DEF ); - current_block->param1.function_name=wcsdup(argv[woptind]); - current_block->param2.function_description=desc?wcsdup(desc):0; + current_block->param1.function_name=halloc_register( current_block, wcsdup(argv[woptind])); + current_block->param2.function_description=desc?halloc_register( current_block, wcsdup(desc)):0; current_block->param3.function_is_binding = is_binding; current_block->param4.function_events = events; + for( i=0; ifunction_name = wcsdup( current_block->param1.function_name ); + e->function_name = current_block->param1.function_name; } - } - + current_block->tok_pos = parser_get_pos(); current_block->skip = 1; @@ -2579,12 +2581,14 @@ static int builtin_for( wchar_t **argv ) int i; current_block->tok_pos = parser_get_pos(); - current_block->param1.for_variable = wcsdup( argv[1] ); + current_block->param1.for_variable = halloc_register( current_block, wcsdup( argv[1] )); for( i=argc-1; i>3; i-- ) { - al_push( ¤t_block->param2.for_vars, wcsdup(argv[ i ] )); + al_push( ¤t_block->param2.for_vars, halloc_register( current_block, wcsdup(argv[ i ] ) ) ); } + halloc_register( current_block, current_block->param2.for_vars.arr ); + if( argc > 3 ) { env_set( current_block->param1.for_variable, argv[3], ENV_LOCAL ); @@ -2669,10 +2673,7 @@ static int builtin_end( wchar_t **argv ) */ if( current_block->loop_status == LOOP_BREAK ) { - while( al_get_count( ¤t_block->param2.for_vars ) ) - { - free( (void *)al_pop( ¤t_block->param2.for_vars ) ); - } + al_truncate( ¤t_block->param2.for_vars, 0 ); } if( al_get_count( ¤t_block->param2.for_vars ) ) @@ -2681,8 +2682,7 @@ static int builtin_end( wchar_t **argv ) env_set( current_block->param1.for_variable, val, ENV_LOCAL); current_block->loop_status = LOOP_NORMAL; current_block->skip = 0; - free(val); - + kill_block = 0; parser_set_pos( current_block->tok_pos ); /* @@ -2901,7 +2901,7 @@ static int builtin_switch( wchar_t **argv ) else { parser_push_block( SWITCH ); - current_block->param1.switch_value = wcsdup( argv[1]); + current_block->param1.switch_value = halloc_register( current_block, wcsdup( argv[1])); current_block->skip=1; current_block->param2.switch_taken=0; } diff --git a/common.c b/common.c index cc873688b..25f0b5443 100644 --- a/common.c +++ b/common.c @@ -125,7 +125,11 @@ wchar_t **list_to_char_arr( void *context, array_list_t *l ) die_mem(); } for( i=0; iargv[0] )); + wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] ))); //fwprintf( stderr, L"run function %ls\n", argv[0] ); if( def == 0 ) { @@ -803,7 +803,7 @@ void exec( job_t *j ) parser_push_block( FUNCTION_CALL ); current_block->param2.function_call_process = p; - current_block->param1.function_name = wcsdup( p->argv[0] ); + current_block->param1.function_name = halloc_register( current_block, wcsdup( p->argv[0] ) ); if( builtin_count_args(p->argv)>1 ) { diff --git a/expand.c b/expand.c index 5b71fe80e..e1916c4de 100644 --- a/expand.c +++ b/expand.c @@ -171,13 +171,11 @@ void expand_variable_array( const wchar_t *val, array_list_t *out ) if( *pos == ARRAY_SEP ) { *pos=0; - al_push( out, wcsdup(start) ); + al_push( out, start==cpy?cpy:wcsdup(start) ); start=pos+1; } } - al_push( out, wcsdup(start) ); - - free(cpy); + al_push( out, start==cpy?cpy:wcsdup(start) ); } } diff --git a/halloc.c b/halloc.c index 4d61601c3..741f4862e 100644 --- a/halloc.c +++ b/halloc.c @@ -1,5 +1,9 @@ /** \file halloc.c - A hierarchical memory allocation system + + 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. + */ #include "config.h" @@ -14,6 +18,7 @@ typedef struct halloc { array_list_t children; + array_list_t hchildren; long long data[0]; } halloc_t; @@ -26,53 +31,48 @@ static halloc_t *halloc_from_data( void *data ) void *halloc( void *context, size_t size ) { - halloc_t *res = (halloc_t *)calloc( 1, sizeof(halloc_t) + size ); - if( !res ) + + halloc_t *me, *parent; + + me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size ); + + if( !me ) return 0; - - al_init( &res->children ); - + + al_init( &me->children ); + if( context ) - { - halloc_t *parent = halloc_from_data( context ); - al_push( &parent->children, &res->data ); + { + parent = halloc_from_data( context ); + al_push( &parent->hchildren, &me->data ); } - return &res->data; + + return &me->data; } +void *halloc_register( void *context, void *data ) +{ + halloc_t *me; + if( !context ) + return data; + + me = halloc_from_data( context ); + al_push( &me->children, data ); + return data; +} + + void halloc_free( void *context ) { halloc_t *me; if( !context ) return; - + me = halloc_from_data( context ); - al_foreach( &me->children, (void (*)(const void *))&halloc_free ); + al_foreach( &me->hchildren, (void (*)(const void *))&halloc_free ); + al_foreach( &me->children, (void (*)(const void *))&free ); al_destroy( &me->children ); + al_destroy( &me->hchildren ); free(me); } -wchar_t *halloc_wcsdup( void *context, const wchar_t *in ) -{ - size_t len=wcslen(in); - wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1)); - if( out == 0 ) - { - die_mem(); - } - - memcpy( out, in, sizeof( wchar_t)*(len+1)); - return out; -} - -wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c ) -{ - wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) ); - if( res == 0 ) - { - die_mem(); - } - wcsncpy( res, in, c ); - res[c] = L'\0'; - return res; -} diff --git a/halloc.h b/halloc.h index a3bea49f0..089318901 100644 --- a/halloc.h +++ b/halloc.h @@ -1,18 +1,35 @@ -/** \file halloc.h - A hierarchical memory allocation system +/** \file halloc.h + + 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. + */ /** Allocate new memory using specified parent memory context. If \c - context is null, a new root context is created. + context is null, a new root context is created. Context _must_ be + either 0 or the result of a previous call to halloc. + + If \c context is null, the resulting block must be freed with a + call to halloc_free(). + + If \c context is not null, the resulting memory block must never be + explicitly freed, it will be automatically freed whenever the + parent context is freed. */ void *halloc( void *context, size_t size ); /** - Free memory context and all children. Only root contexts may be - freed explicitly. + Free memory context and all children contexts. Only root contexts + may be freed explicitly. */ void halloc_free( void *context ); -wchar_t *halloc_wcsdup( void *context, const wchar_t *str ); -wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c ); +/** + Free the memory pointed to by \c data when the memory pointed to by + \c context is free:d. Note that this will _not_ turn the specified + memory area into a valid halloc context. Only memory areas created + using a call to halloc() can be used as a context. +*/ +void *halloc_register( void *context, void *data ); diff --git a/parser.c b/parser.c index 80fcaf7c9..714067b62 100644 --- a/parser.c +++ b/parser.c @@ -339,7 +339,7 @@ static int block_count( block_t *b ) void parser_push_block( int type ) { - block_t *new = calloc( 1, sizeof( block_t )); + block_t *new = halloc( 0, sizeof( block_t )); new->src_lineno = parser_get_lineno(); new->src_filename = parser_current_filename()?intern(parser_current_filename()):0; @@ -376,9 +376,6 @@ void parser_push_block( int type ) void parser_pop_block() { - - event_block_t *eb, *eb_next; - // debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 ); if( (current_block->type != FUNCTION_DEF ) && @@ -388,51 +385,9 @@ void parser_pop_block() env_pop(); } - switch( current_block->type) - { - case FOR: - { - free( current_block->param1.for_variable ); - al_foreach( ¤t_block->param2.for_vars, - (void (*)(const void *))&free ); - al_destroy( ¤t_block->param2.for_vars ); - break; - } - - case SWITCH: - { - free( current_block->param1.switch_value ); - break; - } - - case FUNCTION_DEF: - { - free( current_block->param1.function_name ); - free( current_block->param2.function_description ); - al_foreach( current_block->param4.function_events, - (void (*)(const void *))&event_free ); - al_destroy( current_block->param4.function_events ); - free( current_block->param4.function_events ); - break; - } - - case FUNCTION_CALL: - { - free( current_block->param1.function_name ); - break; - } - - } - - for( eb=current_block->first_event_block; eb; eb=eb_next ) - { - eb_next = eb->next; - free(eb); - } - block_t *old = current_block; current_block = current_block->outer; - free( old ); + halloc_free( old ); } const wchar_t *parser_get_block_desc( int block ) @@ -1440,7 +1395,7 @@ static void parse_job_main_loop( process_t *p, Display help for count */ p->type = INTERNAL_BUILTIN; - wcscpy( p->actual_cmd, L"count" ); + p->actual_cmd = L"count"; } @@ -1465,7 +1420,7 @@ static void parse_job_main_loop( process_t *p, unmatched_wildcard = 1; if( !unmatched ) { - unmatched = halloc_wcsdup( j, tok_last( tok )); + unmatched = halloc_register( j, wcsdup( tok_last( tok ))); unmatched_pos = tok_get_pos( tok ); } @@ -1532,9 +1487,7 @@ static void parse_job_main_loop( process_t *p, { case TOK_STRING: { - wchar_t *tmp = expand_one( wcsdup( tok_last( tok ) ), 0); - target = halloc_wcsdup( j, tmp ); - free( tmp ); + target = (wchar_t *)halloc_register( j, expand_one( wcsdup( tok_last( tok ) ), 0)); if( target == 0 && error_code == 0 ) { @@ -1955,13 +1908,12 @@ static int parse_job( process_t *p, */ if( current_block->skip ) { - p->actual_cmd = wcsdup(L""); + p->actual_cmd = L""; } else { - - p->actual_cmd = get_filename( (wchar_t *)al_get( &args, 0 ) ); - + p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( &args, 0 ) )); + /* Check if the specified command exists */ @@ -2236,13 +2188,11 @@ static void eval_job( tokenizer *tok ) if( newline ) stop_pos = mini( stop_pos, newline - tok_string(tok) ); - j->command = halloc_wcsndup( j, - tok_string(tok)+start_pos, - stop_pos-start_pos ); + j->command = halloc_register( j, wcsndup( tok_string(tok)+start_pos, + stop_pos-start_pos )); } else - j->command = halloc_wcsdup( j, - L"" ); + j->command = L""; if( profile ) { diff --git a/proc.c b/proc.c index a52107c69..08a74cb94 100644 --- a/proc.c +++ b/proc.c @@ -109,28 +109,6 @@ void proc_init() sb_init( &event_status ); } - -/** - Recursively free a process and those following it -*/ -static void free_process( process_t *p ) -{ - wchar_t **arg; - - if( p==0 ) - return; - - free_process( p->next ); - free( p->actual_cmd ); - if( p->argv != 0 ) - { - for( arg=p->argv; *arg; arg++ ) - { - free( *arg ); - } - } -} - /** Remove job from list of jobs */ @@ -164,15 +142,7 @@ static int job_remove( job_t *j ) */ void job_free( job_t * j ) { - io_data_t *io, *ionext; - -// fwprintf( stderr, L"Remove job %d (%ls)\n", j->job_id, j->command ); - job_remove( j ); - - /* Then free ourselves */ - free_process( j->first_process); - halloc_free( j ); }