From 81b84ef106277b67b22a344f05921e04b6c183d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 3 Dec 1996 13:41:19 -0800 Subject: [PATCH] callbacks modified to handle recursive calls better Rev: src/backend.c:1.7 Rev: src/builtin_functions.c:1.15 Rev: src/callback.c:1.3 Rev: src/callback.h:1.2 Rev: src/gc.h:1.5 Rev: src/interpret.c:1.15 Rev: src/interpret.h:1.5 Rev: src/main.c:1.12 --- src/backend.c | 4 +-- src/builtin_functions.c | 4 +-- src/callback.c | 57 +++++++++++++++++++++++++++++++++++------ src/callback.h | 12 ++++++--- src/gc.h | 2 +- src/interpret.c | 4 +-- src/interpret.h | 2 +- src/main.c | 4 +-- 8 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/backend.c b/src/backend.c index f7cfb922c8..a951c59bca 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 8b422b2431..6b1615cd6e 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 e900dd4530..ff150380d4 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 29c36594be..104847cf2d 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 927d1a5e05..9f6cb70743 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 2901c77bcc..1cb4bc837b 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 0733429568..618d7b3de7 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 725f4b5c78..0938c231df 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, -- GitLab