diff --git a/src/backend.c b/src/backend.c index f3fe6f8c31a37d5e510e41ff23c8a239e9dc3196..acaca8659d13a4dba447943d64f2df7bef24ffed 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.15 1997/08/30 18:35:21 grubba Exp $"); +RCSID("$Id: backend.c,v 1.16 1997/10/23 03:15:30 hubbe Exp $"); #include "backend.h" #include <errno.h> #ifdef HAVE_SYS_TYPES_H @@ -24,6 +24,8 @@ RCSID("$Id: backend.c,v 1.15 1997/08/30 18:35:21 grubba Exp $"); #include <sys/select.h> #endif +#include <sys/stat.h> + #define SELECT_READ 1 #define SELECT_WRITE 2 @@ -185,8 +187,13 @@ void *query_write_callback_data(int fd) } #ifdef DEBUG + +struct callback_list do_debug_callbacks; + void do_debug(void) { + int e; + struct stat tmp; extern void check_all_arrays(void); extern void check_all_mappings(void); extern void check_all_programs(void); @@ -200,6 +207,32 @@ void do_debug(void) check_all_programs(); verify_all_objects(); verify_shared_strings_tables(); + + call_callback(& do_debug_callbacks, 0); + + for(e=0;e<=max_fd;e++) + { + if(FD_ISSET(e,&selectors.read) || FD_ISSET(e,&selectors.write)) + { + int ret; + do { + ret=fstat(e, &tmp); + }while(ret < 0 && errno == EINTR); + + if(ret<0) + { + switch(errno) + { + case EBADF: + fatal("Backend filedescriptor is bad.\n"); + break; + case ENOENT: + fatal("Backend filedescriptor is not.\n"); + break; + } + } + } + } } #endif diff --git a/src/backend.h b/src/backend.h index 5aded4daa9bba93b8ead886c330b0ba867ea925f..e58a610727d42f9f59c2e74f5818d8f1db809210 100644 --- a/src/backend.h +++ b/src/backend.h @@ -13,6 +13,7 @@ extern struct timeval current_time; extern struct timeval next_timeout; typedef void (*file_callback)(int,void *); +extern struct callback_list do_debug_callbacks; /* Prototypes begin here */ struct selectors; diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c index 26526b881cd0a5650bab922402874254ef04bfd4..d508736c673088a0de4b368e2462056f0a47b6d0 100644 --- a/src/modules/call_out/call_out.c +++ b/src/modules/call_out/call_out.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: call_out.c,v 1.13 1997/08/30 18:36:19 grubba Exp $"); +RCSID("$Id: call_out.c,v 1.14 1997/10/23 03:15:41 hubbe Exp $"); #include "array.h" #include "dynamic_buffer.h" #include "object.h" @@ -46,15 +46,28 @@ static int call_buffer_size; /* no of pointers in buffer */ #define CAR(X) (((X)<<1)+1) #define CDR(X) (((X)<<1)+2) #define PARENT(X) (((X)-1)>>1) -#define CALL(X) call_buffer[(X)] +#define CALL(X) (call_buffer[(X)]) #define CMP(X,Y) my_timercmp(& CALL(X).tv, <, & CALL(Y).tv) #define SWAP(X,Y) do{ call_out _tmp=CALL(X); CALL(X)=CALL(Y); CALL(Y)=_tmp; } while(0) +#ifdef DEBUG +static int inside_call_out=0; +#define PROTECT_CALL_OUTS() \ + if(inside_call_out) fatal("Recursive call in call_out module.\n"); \ + inside_call_out=1 + +#define UNPROTECT_CALL_OUTS() \ + inside_call_out=0 +#else +#define PROTECT_CALL_OUTS() +#define UNPROTECT_CALL_OUTS() +#endif + +#ifdef DEBUG static void verify_call_outs(void) { -#ifdef DEBUG struct array *v; - int e; + int e,d; if(!d_flag) return; if(!call_buffer) return; @@ -78,9 +91,37 @@ static void verify_call_outs(void) if(v->malloced_size<v->size) fatal("Impossible array.\n"); + + if(!v->size) + fatal("Call out array of zero size!\n"); + + if(d_flag>4) + { + for(d=e+1;d<num_pending_calls;d++) + if(CALL(e).args == CALL(d).args) + fatal("Duplicate call out in heap.\n"); + } } -#endif + + for(d=0;d<10 && e<call_buffer_size;d++,e++) + { + CALL(e).caller=(struct object *)1; /* Illegal value */ + CALL(e).args=(struct array *)1; /* Illegal value */ + } +} + +static struct callback *verify_call_out_callback=0; +void do_verify_call_outs(struct callback *foo, void *x, void *y) +{ + PROTECT_CALL_OUTS(); + verify_call_outs(); + UNPROTECT_CALL_OUTS(); } +#else +#define verify_call_outs() +#endif + + static void adjust_down(int pos) { @@ -156,7 +197,7 @@ static struct array * new_call_out(int num_arg,struct svalue *argp) }else{ new_buffer=(call_out *)realloc((char *)call_buffer, sizeof(call_out)*call_buffer_size*2); if(!new_buffer) - error("Not enough memorry for another call_out\n"); + error("Not enough memory for another call_out\n"); call_buffer_size*=2; call_buffer=new_buffer; } @@ -238,8 +279,7 @@ void f_call_out(INT32 args) sp[1-args]=tmp; v=new_call_out(args,sp-args); - v->refs++; - push_array(v); + ref_push_array(v); /* We do not add this callback until we actually have * call outs to take care of. @@ -249,6 +289,12 @@ void f_call_out(INT32 args) if(!mem_callback) mem_callback=add_memory_usage_callback(count_memory_in_call_outs,0,0); + +#ifdef DEBUG + if(!verify_call_out_callback) + verify_call_out_callback=add_to_callback(& do_debug_callbacks, + do_verify_call_outs, 0, 0); +#endif } void do_call_outs(struct callback *ignored, void *ignored_too, void *arg) @@ -266,9 +312,15 @@ void do_call_outs(struct callback *ignored, void *ignored_too, void *arg) { /* unlink call out */ call_out c; + + PROTECT_CALL_OUTS(); c=CALL(0); - CALL(0)=CALL(--num_pending_calls); - adjust_down(0); + if(--num_pending_calls) + { + CALL(0)=CALL(num_pending_calls); + adjust_down(0); + } + UNPROTECT_CALL_OUTS(); if(c.caller) free_object(c.caller); @@ -337,6 +389,8 @@ void f_find_call_out(INT32 args) { int e; verify_call_outs(); + + PROTECT_CALL_OUTS(); e=find_call_out(sp - args); pop_n_elems(args); if(e==-1) @@ -348,6 +402,7 @@ void f_find_call_out(INT32 args) }else{ push_int(CALL(e).tv.tv_sec - current_time.tv_sec); } + UNPROTECT_CALL_OUTS(); verify_call_outs(); } @@ -355,6 +410,7 @@ void f_remove_call_out(INT32 args) { int e; verify_call_outs(); + PROTECT_CALL_OUTS(); e=find_call_out(sp-args); if(e!=-1) { @@ -376,6 +432,7 @@ void f_remove_call_out(INT32 args) sp->u.integer=-1; sp++; } + UNPROTECT_CALL_OUTS(); verify_call_outs(); } @@ -388,6 +445,7 @@ struct array *get_all_call_outs(void) struct array *ret; verify_call_outs(); + PROTECT_CALL_OUTS(); ret=allocate_array_no_init(num_pending_calls,0); for(e=0;e<num_pending_calls;e++) { @@ -413,6 +471,7 @@ struct array *get_all_call_outs(void) ITEM(ret)[e].type=T_ARRAY; ITEM(ret)[e].u.array=v; } + UNPROTECT_CALL_OUTS(); return ret; } @@ -436,13 +495,6 @@ void free_all_call_outs(void) call_buffer=NULL; } -#ifdef DEBUG -void verify_all_call_outs(void) -{ - verify_call_outs(); -} -#endif - void pike_module_init(void) { add_efun("call_out",f_call_out,"function(function,float|int,mixed...:mixed)",OPT_SIDE_EFFECT); diff --git a/src/modules/call_out/test_co.pike b/src/modules/call_out/test_co.pike index 8403cc15304a93c6b0feb5d768af61ba623d5480..a54907eb47a175f49014375ac8e3792dba4c300d 100644 --- a/src/modules/call_out/test_co.pike +++ b/src/modules/call_out/test_co.pike @@ -1,6 +1,6 @@ #!/usr/local/bin/pike -/* $Id: test_co.pike,v 1.2 1997/05/31 22:04:11 grubba Exp $ */ +/* $Id: test_co.pike,v 1.3 1997/10/23 03:15:42 hubbe Exp $ */ void verify(); @@ -10,8 +10,7 @@ int cnt; #define FUN(X) void X() \ { \ - fc[X]--; \ - if(!(++cnt & 15)) { verify(); werror("."); } \ + if(!(--fc[X] && (++cnt & 15))) { verify(); werror("."); } \ } FUN(f0) @@ -41,7 +40,8 @@ void verify() exit(1); } } - if(!sizeof(ff)) exit(0); + if(!sizeof(ff)) { werror("\n"); exit(0); } + gc(); } mixed co(mixed func, mixed ... args) @@ -79,8 +79,8 @@ void do_remove() verify(); werror("."); } - werror("\nWaiting to exit \n"); - call_out(exit,5,30,1); + werror("\nWaiting to exit "); + call_out(exit,30,1); } int main() @@ -115,6 +115,24 @@ int main() } } + werror("\nTesting beginning of heap ..."); + + verify(); + + mixed *tmp=allocate(100); + for(int e=0;e<sizeof(tmp);e++) tmp[e]=co(f0,-50.0); + + verify(); + + for(int e=0;e<sizeof(tmp);e++) + { + if(zero_type(rco(tmp[e]))==1) + { + werror("Remove call out failed!!!\n"); + exit(1); + } + } + verify(); werror("\nWaiting ");