diff --git a/src/backend.c b/src/backend.c index f7cfb922c8f8d5831d543f30632e4cabd2fb4c8e..a951c59bca7f717312f4a59d93ce2c27c00ede80 100644 --- a/src/backend.c +++ b/src/backend.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: backend.c,v 1.6 1996/11/22 00:05:41 hubbe Exp $"); +RCSID("$Id: backend.c,v 1.7 1996/12/03 21:41:15 hubbe Exp $"); #include "backend.h" #include <errno.h> #ifdef HAVE_SYS_TYPES_H @@ -45,7 +45,7 @@ static int max_fd; struct timeval current_time; struct timeval next_timeout; -static struct callback *backend_callbacks = 0; +static struct callback_list backend_callbacks; struct callback *add_backend_callback(callback_func call, void *arg, diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 8b422b2431a86ca84fcd78045f39f245cf7cd41f..6b1615cd6ea4bfe2de94d870175e1bdd6d95c4f7 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.14 1996/12/02 07:02:25 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.15 1996/12/03 21:41:15 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "macros.h" @@ -595,7 +595,7 @@ void f_throw(INT32 args) throw(); } -static struct callback *exit_callbacks=0; +static struct callback_list exit_callbacks; struct callback *add_exit_callback(callback_func call, void *arg, diff --git a/src/callback.c b/src/callback.c index e900dd45300c48ab545872f0736b1e872c3d849a..ff150380d4d1d551a55bf5c38fce9a5317f15270 100644 --- a/src/callback.c +++ b/src/callback.c @@ -33,6 +33,30 @@ static struct callback_block *callback_chunks=0; static struct callback *first_callback =0; static struct callback *free_callbacks =0; +#ifdef DEBUG +static void check_callback_chain(struct callback_list *lst) +{ + int len=0; + struct callback *foo; + for(foo=lst->callbacks;foo;foo=foo->next) + { + if((len & 1024)==1023) + { + int len2=0; + struct callback *tmp; + for(tmp=foo->next;tmp && len2<=len;tmp=tmp->next) + { + if(tmp==foo) + fatal("Callback list is cyclic!!!\n"); + } + } + len++; + } +} +#else +#define check_callback_chain(X) +#endif + /* Return the first free callback struct, allocate more if needed */ static struct callback *get_free_callback() { @@ -58,12 +82,24 @@ static struct callback *get_free_callback() /* Traverse a linked list of callbacks and call all the active callbacks * in the list. Deactivated callbacks are freed and placed in the free list. */ -void call_callback(struct callback **ptr, void *arg) +void call_callback(struct callback_list *lst, void *arg) { - struct callback *l; + int this_call; + struct callback *l,**ptr; + + lst->num_calls++; + this_call=lst->num_calls; + + check_callback_chain(lst); + ptr=&lst->callbacks; while(l=*ptr) { - if(l->call) l->call(l,l->arg, arg); + if(l->call) + { + l->call(l,l->arg, arg); + if(lst->num_calls != this_call) return; + } + check_callback_chain(lst); if(!l->call) { @@ -73,11 +109,12 @@ void call_callback(struct callback **ptr, void *arg) }else{ ptr=& l->next; } + check_callback_chain(lst); } } /* Add a callback to the linked list pointed to by ptr. */ -struct callback *add_to_callback(struct callback **ptr, +struct callback *add_to_callback(struct callback_list *lst, callback_func call, void *arg, callback_func free_func) @@ -87,8 +124,10 @@ struct callback *add_to_callback(struct callback **ptr, l->call=call; l->arg=arg; - l->next=*ptr; - *ptr=l; + l->next=lst->callbacks; + lst->callbacks=l; + + check_callback_chain(lst); return l; } @@ -103,9 +142,11 @@ void *remove_callback(struct callback *l) } /* Free all the callbacks in a linked list of callbacks */ -void free_callback(struct callback **ptr) +void free_callback(struct callback_list *lst) { - struct callback *l; + struct callback *l,**ptr; + check_callback_chain(lst); + ptr=& lst->callbacks; while(l=*ptr) { if(l->arg && l->free_func) diff --git a/src/callback.h b/src/callback.h index 29c36594beb40f295f0aa97a7bd4c1870b9b9ee8..104847cf2dc831b5bb972f7ee42de122d132fd11 100644 --- a/src/callback.h +++ b/src/callback.h @@ -10,18 +10,24 @@ struct callback; +struct callback_list +{ + struct callback *callbacks; + int num_calls; +}; + typedef void (*callback_func)(struct callback *, void *,void *); /* Prototypes begin here */ struct callback; struct callback_block; -void call_callback(struct callback **ptr, void *arg); -struct callback *add_to_callback(struct callback **ptr, +void call_callback(struct callback_list *lst, void *arg); +struct callback *add_to_callback(struct callback_list *lst, callback_func call, void *arg, callback_func free_func); void *remove_callback(struct callback *l); -void free_callback(struct callback **ptr); +void free_callback(struct callback_list *ptr); void cleanup_callbacks(); /* Prototypes end here */ diff --git a/src/gc.h b/src/gc.h index 927d1a5e0504ba6e1932eb15b79ad6f0fa5bf3e0..9f6cb707431cdcbc5292df44361885e88bdc2802 100644 --- a/src/gc.h +++ b/src/gc.h @@ -11,7 +11,7 @@ extern INT32 num_allocs; extern INT32 alloc_threshold; extern struct callback *gc_evaluator_callback; -extern struct callback *evaluator_callbacks; +extern struct callback_list evaluator_callbacks; #define ADD_GC_CALLBACK() gc_evaluator_callback=add_to_callback(&evaluator_callbacks,(callback_func)do_gc,0,0) diff --git a/src/interpret.c b/src/interpret.c index 2901c77bcc622234f99e38a483fb7e4f5fed13ac..1cb4bc837b99b27edfe47bb02ae657cd0e1180ec 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.14 1996/12/01 13:03:55 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.15 1996/12/03 21:41:18 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -307,7 +307,7 @@ void pop_n_elems(INT32 x) } -struct callback *evaluator_callbacks =0; +struct callback_list evaluator_callbacks; /* This function is called 'every now and then'. (1-10000 / sec or so) * It should do anything that needs to be done fairly often. diff --git a/src/interpret.h b/src/interpret.h index 073342956868ebc31da63d6d33872c2feb888909..618d7b3de7926ae45f52c0189dea8e2e58aa41a7 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -103,6 +103,6 @@ extern struct frame *fp; /* frame pointer */ extern int stack_size; extern int evaluator_stack_malloced, mark_stack_malloced; struct callback; -extern struct callback *evaluator_callbacks; +extern struct callback_list evaluator_callbacks; #endif diff --git a/src/main.c b/src/main.c index 725f4b5c78223cb5e7154b419d86ffacaebb4090..0938c231df4e7ef51672fb3e1dd1cf8a69fb4529 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: main.c,v 1.11 1996/11/22 20:58:23 hubbe Exp $"); +RCSID("$Id: main.c,v 1.12 1996/12/03 21:41:19 hubbe Exp $"); #include "types.h" #include "backend.h" #include "module.h" @@ -40,7 +40,7 @@ int a_flag=0; int l_flag=0; int p_flag=0; -static struct callback *post_master_callbacks =0; +static struct callback_list post_master_callbacks; struct callback *add_post_master_callback(callback_func call, void *arg,