From 5f06241c99ad43ceb52a4ce6ea5e1ea9429c9db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sun, 11 Apr 1999 19:24:19 -0700 Subject: [PATCH] atexit() and weak arrays implemented Rev: src/array.c:1.46 Rev: src/array.h:1.17 Rev: src/builtin_functions.c:1.166 Rev: src/encode.c:1.31 Rev: src/main.c:1.70 Rev: src/object.c:1.70 Rev: src/signal_handler.c:1.123 Rev: src/signal_handler.h:1.7 --- src/array.c | 44 +++++++++++++- src/array.h | 8 ++- src/builtin_functions.c | 30 ++++++---- src/encode.c | 9 ++- src/main.c | 7 ++- src/object.c | 19 +----- src/signal_handler.c | 125 +++++++++++++++++++++++++--------------- src/signal_handler.h | 15 ++++- 8 files changed, 167 insertions(+), 90 deletions(-) diff --git a/src/array.c b/src/array.c index 57a3289ec4..ea2ae488ed 100644 --- a/src/array.c +++ b/src/array.c @@ -20,7 +20,7 @@ #include "main.h" #include "security.h" -RCSID("$Id: array.c,v 1.45 1999/03/19 11:40:12 hubbe Exp $"); +RCSID("$Id: array.c,v 1.46 1999/04/12 02:24:10 hubbe Exp $"); struct array empty_array= { @@ -1685,7 +1685,7 @@ void check_all_arrays(void) void gc_mark_array_as_referenced(struct array *a) { - if(gc_mark(a)) + if(gc_mark(a) && !(a->flags & ARRAY_WEAK_FLAG)) if(a->type_field & BIT_COMPLEX) gc_mark_svalues(ITEM(a), a->size); } @@ -1751,7 +1751,45 @@ void gc_free_all_unreferenced_arrays(void) free_array(a); a=next; - }else{ + } + else if(a->flags & ARRAY_WEAK_FLAG) + { + int e; + add_ref(a); + + if(a->flags & ARRAY_WEAK_SHRINK) + { + int d=0; + for(e=0;e<a->size;e++) + { + if(a->item[e].type <= MAX_COMPLEX && gc_do_free(a->item[e].u.refs)) + free_svalue(a->item+e); + else + a->item[d++]=a->item[e]; + } + a->size=e; + }else{ + for(e=0;e<a->size;e++) + { + if(a->item[e].type <= MAX_COMPLEX && gc_do_free(a->item[e].u.refs)) + { + free_svalue(a->item+e); + a->item[e].type=T_INT; + a->item[e].u.integer=0; + a->item[e].subtype=NUMBER_DESTRUCTED; + a->type_field |= BIT_INT; + } + } + } + + if(!(next=a->next)) + fatal("Null pointer in array list.\n"); + + free_array(a); + a=next; + } + else + { a=a->next; } } while (a != & empty_array); diff --git a/src/array.h b/src/array.h index da0674db11..2b09ba8342 100644 --- a/src/array.h +++ b/src/array.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: array.h,v 1.16 1999/03/06 05:55:39 hubbe Exp $ + * $Id: array.h,v 1.17 1999/04/12 02:24:11 hubbe Exp $ */ #ifndef ARRAY_H #define ARRAY_H @@ -31,8 +31,10 @@ struct array struct svalue item[1]; }; -#define ARRAY_CYCLIC 1 -#define ARRAY_LVALUE 2 +#define ARRAY_WEAK_FLAG 1 +#define ARRAY_CYCLIC 2 +#define ARRAY_LVALUE 4 +#define ARRAY_WEAK_SHRINK 8 extern struct array empty_array; diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 7fbfb62966..eae21cd73a 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.165 1999/04/03 06:10:04 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.166 1999/04/12 02:24:12 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -1872,21 +1872,26 @@ void f_mkmapping(INT32 args) push_mapping(m); } +#define SETFLAG(FLAGS,FLAG,ONOFF) \ + FLAGS = (FLAGS & ~FLAG) | ( ONOFF ? FLAG : 0 ) void f_set_weak_flag(INT32 args) { int ret; - struct mapping *m; - get_all_args("set_weak_flag",args,"%m%i",&m,&ret); - if(ret) + struct svalue *s; + get_all_args("set_weak_flag",args,"%*%i",&s,&ret); + + switch(s->type) { - ret=m->flags & MAPPING_FLAG_WEAK; - m->flags|=MAPPING_FLAG_WEAK; - }else{ - ret=m->flags & MAPPING_FLAG_WEAK; - m->flags&=~MAPPING_FLAG_WEAK; + case T_ARRAY: + SETFLAG(s->u.array->flags,ARRAY_WEAK_FLAG,ret); + break; + case T_MAPPING: + SETFLAG(s->u.mapping->flags,MAPPING_FLAG_WEAK,ret); + break; + default: + SIMPLE_BAD_ARG_ERROR("set_weak_flag",1,"array|mapping"); } - pop_n_elems(args); - push_int(!!ret); + pop_n_elems(args-1); } @@ -3936,6 +3941,7 @@ void f_map_array(INT32 args) push_array(ret); } + void init_builtin_efuns(void) { ADD_EFUN("gethrtime", f_gethrtime,tFunc(tOr(tInt,tVoid),tInt), OPT_EXTERNAL_DEPEND); @@ -4053,7 +4059,7 @@ void init_builtin_efuns(void) ADD_EFUN("mkmapping",f_mkmapping,tFunc(tArr(tSetvar(1,tMix)) tArr(tSetvar(2,tMix)),tMap(tVar(1),tVar(2))),OPT_TRY_OPTIMIZE); /* function(mapping,int:int) */ - ADD_EFUN("set_weak_flag",f_set_weak_flag,tFunc(tMapping tInt,tInt),OPT_SIDE_EFFECT); + ADD_EFUN("set_weak_flag",f_set_weak_flag,tFunc(tSetvar(1,tMix) tInt,tVar(1)),OPT_SIDE_EFFECT); /* function(void|object:object) */ ADD_EFUN("next_object",f_next_object,tFunc(tOr(tVoid,tObj),tObj),OPT_EXTERNAL_DEPEND); diff --git a/src/encode.c b/src/encode.c index 2cee4877ad..b20bce0cac 100644 --- a/src/encode.c +++ b/src/encode.c @@ -24,7 +24,7 @@ #include "stuff.h" #include "version.h" -RCSID("$Id: encode.c,v 1.30 1999/03/07 20:19:43 grubba Exp $"); +RCSID("$Id: encode.c,v 1.31 1999/04/12 02:24:14 hubbe Exp $"); #ifdef _AIX #include <net/nh.h> @@ -886,7 +886,12 @@ static void decode_value2(struct decode_data *data) case 1: decode_value2(data); - f_arrow(2); + if(sp[-2].type==T_INT) + { + pop_stack(); + }else{ + f_arrow(2); + } break; default: diff --git a/src/main.c b/src/main.c index e671588249..a7031447aa 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: main.c,v 1.69 1999/04/08 23:54:29 hubbe Exp $"); +RCSID("$Id: main.c,v 1.70 1999/04/12 02:24:15 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -505,7 +505,9 @@ void low_init_main(void) void exit_main(void) { +#ifdef DO_PIKE_CLEANUP cleanup_objects(); +#endif } void init_main(void) @@ -514,6 +516,7 @@ void init_main(void) void low_exit_main(void) { +#ifdef DO_PIKE_CLEANUP void cleanup_added_efuns(void); void cleanup_pike_types(void); void cleanup_program(void); @@ -611,7 +614,7 @@ void low_exit_main(void) #endif really_clean_up_interpret(); -#ifdef DO_PIKE_CLEANUP + cleanup_callbacks(); free_all_callable_blocks(); exit_destroy_called_mark_hash(); diff --git a/src/object.c b/src/object.c index 7f3f7cf32a..158ab3eca4 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.69 1999/04/08 22:27:08 hubbe Exp $"); +RCSID("$Id: object.c,v 1.70 1999/04/12 02:24:16 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -977,34 +977,19 @@ int object_equal_p(struct object *a, struct object *b, struct processing *p) void cleanup_objects(void) { struct object *o, *next; - for(o=first_object;o;o=next) - { - add_ref(o); - call_destroy(o,1); - next=o->next; - free_object(o); - } for(o=first_object;o;o=next) { add_ref(o); - low_destruct(o, -#ifdef DO_PIKE_CLEANUP - 1 -#else - 0 -#endif - ); + low_destruct(o,1); next=o->next; free_object(o); } -#ifdef DO_PIKE_CLEANUP free_object(master_object); master_object=0; free_program(master_program); master_program=0; destruct_objects_to_destruct(); -#endif } struct array *object_indices(struct object *o) diff --git a/src/signal_handler.c b/src/signal_handler.c index 23635aa226..3dfb49df27 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -22,9 +22,10 @@ #include "operators.h" #include "builtin_functions.h" #include "security.h" +#include "main.h" #include <signal.h> -RCSID("$Id: signal_handler.c,v 1.122 1999/04/09 04:48:43 hubbe Exp $"); +RCSID("$Id: signal_handler.c,v 1.123 1999/04/12 02:24:17 hubbe Exp $"); #ifdef HAVE_PASSWD_H # include <passwd.h> @@ -119,8 +120,8 @@ extern int fd_from_object(struct object *o); static int set_priority( int pid, char *to ); - static struct svalue signal_callbacks[MAX_SIGNALS]; +static void (*default_signals[MAX_SIGNALS])(INT32); static unsigned char sigbuf[SIGNAL_BUFFER]; static int firstsig, lastsig; static struct callback *signal_evaluator_callback =0; @@ -452,20 +453,8 @@ void check_signals(struct callback *foo, void *bar, void *gazonk) if(IS_ZERO(signal_callbacks + sigbuf[lastsig])) { - switch(sigbuf[lastsig]) - { -#ifdef SIGINT - case SIGINT: -#endif -#ifdef SIGHUP - case SIGHUP: -#endif -#ifdef SIGQUIT - case SIGQUIT: -#endif - push_int(1); - f_exit(1); - } + if(default_signals[sigbuf[lastsig]]) + default_signals[sigbuf[lastsig]](sigbuf[lastsig]); }else{ push_int(sigbuf[lastsig]); apply_svalue(signal_callbacks + sigbuf[lastsig], 1); @@ -551,35 +540,29 @@ static void f_signal(int args) switch(signum) { #ifdef USE_SIGCHLD - case SIGCHLD: - func=receive_sigchild; - break; + case SIGCHLD: + func=receive_sigchild; + break; #endif - + #ifdef SIGPIPE - case SIGPIPE: - func=(sigfunctype) SIG_IGN; - break; -#endif - -#ifdef SIGHUP - case SIGHUP: -#endif -#ifdef SIGINT - case SIGINT: -#endif -#ifdef SIGQUIT - case SIGQUIT: + case SIGPIPE: + func=(sigfunctype) SIG_IGN; + break; #endif - func=receive_signal; + + default: + if(default_signals[signum]) + func=receive_signal; + else + func=(sigfunctype) SIG_DFL; break; - - default: - func=(sigfunctype) SIG_DFL; } } else { if(IS_ZERO(sp+1-args)) { + /* Fixme: this can disrupt sigchild and other important signal handling + */ func=(sigfunctype) SIG_IGN; }else{ func=receive_signal; @@ -594,6 +577,15 @@ static void f_signal(int args) pop_n_elems(args); } +void set_default_signal_handler(int signum, void (*func)(INT32)) +{ + int is_on=!!IS_ZERO(signal_callbacks+signum); + int want_on=!!func; + default_signals[signum]=func; + if(is_on!=want_on) + my_signal(signum, want_on ? receive_signal : (sigfunctype) SIG_DFL); +} + static void f_signum(int args) { int i; @@ -2734,6 +2726,52 @@ static RETSIGTYPE fatal_signal(int signum) } #endif + + +static struct array *atexit_functions; + +static void run_atexit_functions(struct callback *cb, void *arg,void *arg2) +{ + if(atexit_functions) + { + push_array(atexit_functions); + atexit_functions=0; + f_reverse(1); + f_call_function(1); + pop_stack(); + } +} + +static void do_signal_exit(INT32 sig) +{ + push_int(sig); + f_exit(1); +} + +void f_atexit(INT32 args) +{ + if(!atexit_functions) + { +#ifdef SIGHUP + set_default_signal_handler(SIGHUP, do_signal_exit); +#endif +#ifdef SIGINT + set_default_signal_handler(SIGINT, do_signal_exit); +#endif +#ifdef SIGQUIT + set_default_signal_handler(SIGQUIT, do_signal_exit); +#endif + add_exit_callback(run_atexit_functions,0,0); + atexit_functions=low_allocate_array(0,1); + } + + f_aggregate(args); + atexit_functions=append_array(atexit_functions,sp-1); + atexit_functions->flags |= ARRAY_WEAK_FLAG | ARRAY_WEAK_SHRINK; + pop_stack(); +} + + void init_signals(void) { int e; @@ -2769,17 +2807,6 @@ void init_signals(void) my_signal(SIGFPE, SIG_IGN); #endif -#ifdef SIGINT - my_signal(SIGINT, receive_signal); -#endif - -#ifdef SIGHUP - my_signal(SIGHUP, receive_signal); -#endif - -#ifdef SIGQUIT - my_signal(SIGQUIT, receive_signal); -#endif for(e=0;e<MAX_SIGNALS;e++) signal_callbacks[e].type=T_INT; @@ -2854,6 +2881,8 @@ void init_signals(void) /* function(int:int) */ ADD_EFUN("ualarm",f_ualarm,tFunc(tInt,tInt),OPT_SIDE_EFFECT); + + ADD_EFUN("atexit",f_atexit,tFuncV( ,tMix,tVoid),OPT_SIDE_EFFECT); #endif } diff --git a/src/signal_handler.h b/src/signal_handler.h index 5dff97b625..e42f56ec20 100644 --- a/src/signal_handler.h +++ b/src/signal_handler.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: signal_handler.h,v 1.6 1998/03/28 14:59:32 grubba Exp $ + * $Id: signal_handler.h,v 1.7 1999/04/12 02:24:19 hubbe Exp $ */ #ifndef SIGNAL_H #define SIGNAL_H @@ -13,13 +13,22 @@ typedef RETSIGTYPE (*sigfunctype) (int); /* Prototypes begin here */ -struct wait_data; struct sigdesc; void my_signal(int sig, sigfunctype fun); +void check_signals(struct callback *foo, void *bar, void *gazonk); +void set_default_signal_handler(int signum, void (*func)(INT32)); +void process_started(pid_t pid); +void process_done(pid_t pid); +struct wait_data; struct pid_status; +struct perishables; +struct plimit; +struct perishables; +void f_set_priority( INT32 args ); void f_create_process(INT32 args); void f_fork(INT32 args); -void check_signals(struct callback *foo, void *bar, void *gazonk); +void f_kill(INT32 args); +void f_atexit(INT32 args); void init_signals(void); void exit_signals(void); /* Prototypes end here */ -- GitLab