From d4828ce85db94e99ea6a8f2323cd102e3e12e068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Thu, 17 Jul 1997 18:44:28 -0700 Subject: [PATCH] bugs fixed Rev: src/modules/files/file.c:1.48 Rev: src/modules/files/file.h:1.4 Rev: src/modules/files/socket.c:1.12 Rev: src/object.c:1.20 Rev: src/pike_macros.h:1.3 Rev: src/program.c:1.35 Rev: src/program.h:1.16 --- src/modules/files/file.c | 40 ++++++++++------- src/modules/files/file.h | 1 - src/modules/files/socket.c | 26 ++++++++--- src/object.c | 54 ++++++++++++++++------ src/pike_macros.h | 1 + src/program.c | 92 +++++++++++++++++++++++++++----------- src/program.h | 2 + 7 files changed, 152 insertions(+), 64 deletions(-) diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 6dae91cd4d..0cb1771971 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -6,7 +6,7 @@ #define READ_BUFFER 8192 #include "global.h" -RCSID("$Id: file.c,v 1.47 1997/07/03 02:36:16 grubba Exp $"); +RCSID("$Id: file.c,v 1.48 1997/07/18 01:44:26 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "stralloc.h" @@ -91,7 +91,6 @@ static void file_write_callback(int fd, void *data); static void init_fd(int fd, int open_mode) { files[fd].refs=1; - files[fd].fd=fd; files[fd].open_mode=open_mode; files[fd].id.type=T_INT; files[fd].id.u.integer=0; @@ -106,16 +105,29 @@ static void init_fd(int fd, int open_mode) static int close_fd(int fd) { #ifdef DEBUG - if(fd < 0) + if(fd < 0 || fd>=MAX_OPEN_FILEDESCRIPTORS) fatal("Bad argument to close_fd()\n"); - if(files[fd].refs<0) + if(files[fd].refs<1) fatal("Wrong ref count in file struct\n"); #endif files[fd].refs--; if(!files[fd].refs) { + set_read_callback(fd,0,0); + set_write_callback(fd,0,0); + + free_svalue(& files[fd].id); + free_svalue(& files[fd].read_callback); + free_svalue(& files[fd].write_callback); + free_svalue(& files[fd].close_callback); + files[fd].id.type=T_INT; + files[fd].read_callback.type=T_INT; + files[fd].write_callback.type=T_INT; + files[fd].close_callback.type=T_INT; + files[fd].open_mode = 0; + while(1) { int i; @@ -150,19 +162,6 @@ static int close_fd(int fd) } break; } - - set_read_callback(fd,0,0); - set_write_callback(fd,0,0); - - free_svalue(& files[fd].id); - free_svalue(& files[fd].read_callback); - free_svalue(& files[fd].write_callback); - free_svalue(& files[fd].close_callback); - files[fd].id.type=T_INT; - files[fd].read_callback.type=T_INT; - files[fd].write_callback.type=T_INT; - files[fd].close_callback.type=T_INT; - files[fd].open_mode = 0; } return 0; } @@ -1098,6 +1097,12 @@ static void exit_file_struct(struct object *o) ERRNO=-1; } +static void (struct object *o) +{ + FD=-1; + ERRNO=-1; +} + static void file_dup(INT32 args) { struct object *o; @@ -1534,6 +1539,7 @@ void pike_module_init() set_init_callback(init_file_struct); set_exit_callback(exit_file_struct); + set_gc_mark_callback(gc_mark_file_struct); file_program=end_program(); add_program_constant("file",file_program,0); diff --git a/src/modules/files/file.h b/src/modules/files/file.h index 548c9e9a48..37e6cbbed0 100644 --- a/src/modules/files/file.h +++ b/src/modules/files/file.h @@ -26,7 +26,6 @@ struct my_file { INT32 refs; - int fd; short open_mode; struct svalue id; struct svalue read_callback; diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index 77fc68de74..0b837cc3c0 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -56,7 +56,7 @@ struct port #define THIS ((struct port *)(fp->current_storage)) -static void do_close(struct port *p) +static void do_close(struct port *p, struct object *o) { retry: if(p->fd >= 0) @@ -65,6 +65,8 @@ static void do_close(struct port *p) if(errno == EINTR) goto retry; + if(query_read_callback(p->fd)==port_accept_callback) + o->refs--; set_read_callback(p->fd,0,0); } @@ -109,7 +111,7 @@ static void port_accept_callback(int fd,void *data) static void port_listen_fd(INT32 args) { int fd; - do_close(THIS); + do_close(THIS,fp->current_object); if(args < 1) error("Too few arguments to port->bind_fd()\n"); @@ -138,9 +140,12 @@ static void port_listen_fd(INT32 args) if(args > 1) { assign_svalue(& THIS->accept_callback, sp+1-args); + set_nonblocking(fd,1); if(!IS_ZERO(& THIS->accept_callback)) + { + fp->current_object->refs++; set_read_callback(fd, port_accept_callback, (void *)THIS); - set_nonblocking(fd,1); + } } THIS->fd=fd; @@ -155,7 +160,7 @@ static void port_bind(INT32 args) int o; int fd,tmp; - do_close(THIS); + do_close(THIS,fp->current_object); if(args < 1) error("Too few arguments to port->bind()\n"); @@ -221,7 +226,10 @@ static void port_bind(INT32 args) { assign_svalue(& THIS->accept_callback, sp+1-args); if(!IS_ZERO(& THIS->accept_callback)) + { + fp->current_object->refs++; set_read_callback(fd, port_accept_callback, (void *)THIS); + } set_nonblocking(fd,1); } @@ -256,7 +264,10 @@ static void port_create(INT32 args) { assign_svalue(& THIS->accept_callback, sp+1-args); if(!IS_ZERO(& THIS->accept_callback)) + { + fp->current_object->refs++; set_read_callback(THIS->fd, port_accept_callback, (void *)THIS); + } set_nonblocking(THIS->fd,1); } } @@ -348,7 +359,7 @@ static void init_port_struct(struct object *o) static void exit_port_struct(struct object *o) { - do_close(THIS); + do_close(THIS,o); free_svalue(& THIS->id); free_svalue(& THIS->accept_callback); THIS->id.type=T_INT; @@ -357,8 +368,11 @@ static void exit_port_struct(struct object *o) void port_setup_program() { + INT32 offset; start_new_program(); - add_storage(sizeof(struct port)); + offset=add_storage(sizeof(struct port)); + map_variable("_accept_callback","mixed",offset+OFFSETOF(port,accept_callback),T_MIXED); + map_variable("_id","mixed",offset+OFFSETOF(port,id),T_MIXED); add_function("bind",port_bind,"function(int,void|mixed:int)",0); add_function("listen_fd",port_listen_fd,"function(int,void|mixed:int)",0); add_function("set_id",port_set_id,"function(mixed:mixed)",0); diff --git a/src/object.c b/src/object.c index 672b75f979..5380ee7ec7 100644 --- a/src/object.c +++ b/src/object.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: object.c,v 1.19 1997/07/14 18:23:20 hubbe Exp $"); +RCSID("$Id: object.c,v 1.20 1997/07/18 01:44:19 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -766,27 +766,55 @@ void gc_mark_object_as_referenced(struct object *o) { if(gc_mark(o)) { - if(o->prog) + int e; + struct frame frame; + struct program *p; + + if(!o || !(p=o->prog)) return; /* Object already destructed */ + o->refs++; + + frame.parent_frame=fp; + frame.current_object=o; /* refs already updated */ + frame.locals=0; + frame.fun=-1; + frame.pc=0; + fp= & frame; + + for(e=p->num_inherits-1; e>=0; e--) { - INT32 e; + int d; - for(e=0;e<(int)o->prog->num_identifier_indexes;e++) + frame.context=p->inherits[e]; + frame.context.prog->refs++; + frame.current_storage=o->storage+frame.context.storage_offset; + + if(frame.context.prog->gc_marked) + frame.context.prog->gc_marked(o); + + + for(d=0;d<(int)frame.context.prog->num_identifiers;d++) { - struct identifier *i; - - i=ID_FROM_INT(o->prog, e); - - if(!IDENTIFIER_IS_VARIABLE(i->flags)) continue; + if(!IDENTIFIER_IS_VARIABLE(frame.context.prog->identifiers[d].flags)) + continue; - if(i->run_time_type == T_MIXED) + if(frame.context.prog->identifiers[d].run_time_type == T_MIXED) { - gc_mark_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1); + struct svalue *s; + s=(struct svalue *)(frame.current_storage + + frame.context.prog->identifiers[d].func.offset); + gc_mark_svalues(s,1); }else{ - gc_mark_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i), - i->run_time_type); + union anything *u; + u=(union anything *)(frame.current_storage + + frame.context.prog->identifiers[d].func.offset); + gc_mark_short_svalue(u,frame.context.prog->identifiers[d].run_time_type); } } + free_program(frame.context.prog); } + + free_object(frame.current_object); + fp = frame.parent_frame; } } diff --git a/src/pike_macros.h b/src/pike_macros.h index 812a50fc11..b27ba57e72 100644 --- a/src/pike_macros.h +++ b/src/pike_macros.h @@ -9,6 +9,7 @@ #include <sys/param.h> #include "pike_memory.h" +#define OFFSETOF(str_type, field) ((long)& (((struct str_type *)0)->field)) #define BASEOF(ptr, str_type, field) \ ((struct str_type *)((char*)ptr - (char*)& (((struct str_type *)0)->field))) diff --git a/src/program.c b/src/program.c index cd31deb163..e0f9fdaf2a 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.34 1997/06/10 20:02:17 hubbe Exp $"); +RCSID("$Id: program.c,v 1.35 1997/07/18 01:44:22 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -695,6 +695,15 @@ void set_exit_callback(void (*exit)(struct object *)) fake_program.exit=exit; } +/* + * This callback is called to allow the object to mark all internal + * structures as 'used'. + */ +void set_gc_mark_callback(void (*m)(struct object *)) +{ + fake_program.gc_marked=m; +} + int low_reference_inherited_identifier(int e,struct pike_string *name) { @@ -896,6 +905,53 @@ int isidentifier(struct pike_string *s) return -1; } +int low_define_variable(struct pike_string *name, + struct pike_string *type, + INT32 flags, + INT32 offset, + INT32 run_time_type) +{ + int n; + struct identifier dummy; + struct reference ref; + + copy_shared_string(dummy.name, name); + copy_shared_string(dummy.type, type); + dummy.flags = 0; + dummy.run_time_type=run_time_type; + dummy.func.offset=offset; + + ref.flags=flags; + ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy; + ref.inherit_offset=0; + + add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); + fake_program.num_identifiers ++; + + n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref; + add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); + fake_program.num_identifier_references ++; + + return n; +} + +int map_variable(char *name, + char *type, + INT32 flags, + INT32 offset, + INT32 run_time_type) +{ + int ret; + struct pike_string *n,*t; + n=make_shared_string(name); + t=parse_type(type); + run_time_type=compile_type_to_runtime_type(t); + ret=low_define_variable(n,t,flags,offset,run_time_type); + free_string(n); + free_string(t); + return ret; +} + /* argument must be a shared string */ int define_variable(struct pike_string *name, struct pike_string *type, @@ -931,32 +987,14 @@ int define_variable(struct pike_string *name, my_yyerror("Illegal to redefine inherited variable with different type."); } else { - struct identifier dummy; - struct reference ref; - - copy_shared_string(dummy.name, name); - copy_shared_string(dummy.type, type); - dummy.flags = 0; - dummy.run_time_type=compile_type_to_runtime_type(type); - - if(dummy.run_time_type == T_FUNCTION) - dummy.run_time_type = T_MIXED; - - dummy.func.offset=add_storage(dummy.run_time_type == T_MIXED ? - sizeof(struct svalue) : - sizeof(union anything)); - - ref.flags=flags; - ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy; - ref.inherit_offset=0; - - add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); - fake_program.num_identifiers ++; - - n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref; - add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); - fake_program.num_identifier_references ++; - + int run_time_type=compile_type_to_runtime_type(type); + if(run_time_type == T_FUNCTION) run_time_type = T_MIXED; + + n=low_define_variable(name, type, flags, + add_storage(run_time_type == T_MIXED ? + sizeof(struct svalue) : + sizeof(union anything)), + run_time_type); } return n; diff --git a/src/program.h b/src/program.h index 6e2b42c41c..3e59542f3d 100644 --- a/src/program.h +++ b/src/program.h @@ -149,6 +149,7 @@ struct program char *linenumbers; void (*init)(struct object *); void (*exit)(struct object *); + void (*gc_marked)(struct object *); #ifdef DEBUG unsigned INT32 checksum; #endif @@ -191,6 +192,7 @@ struct program *end_program(); SIZE_T add_storage(SIZE_T size); void set_init_callback(void (*init)(struct object *)); void set_exit_callback(void (*exit)(struct object *)); +void set_gc_mark_callback(void (*m)(struct object *)); int low_reference_inherited_identifier(int e,struct pike_string *name); int reference_inherited_identifier(struct pike_string *super_name, struct pike_string *function_name); -- GitLab