diff --git a/src/array.c b/src/array.c index fe1fe0db5dace84bebbeaff7caefca15b04e9e85..b12e24b1a12efe96e6bb56897e229daa6c4de495 100644 --- a/src/array.c +++ b/src/array.c @@ -1535,7 +1535,8 @@ void debug_dump_type_field(TYPE_FIELD t) void debug_dump_array(struct array *a) { - fprintf(stderr,"Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n", + fprintf(stderr,"Locatoin=%p Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n", + a, a->refs, a->next, a->prev, diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 13be00f1c5feb93a0955c1d4a320e6e6427aa320..ac872ecf5552543e929b6a464a14b7a437cfee06 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.64 1998/01/29 18:10:53 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.65 1998/01/30 06:19:50 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -617,9 +617,8 @@ void f_throw(INT32 args) { if(args < 1) error("Too few arguments to throw()\n"); - pop_n_elems(args-1); - throw_value=sp[-1]; - sp--; + assign_svalue(&throw_value,sp-args); + pop_n_elems(args); pike_throw(); } diff --git a/src/error.c b/src/error.c index c21871d1b9fb9ca9628596ffefce0f9093c4f294..3acf9da06ccae64e2c0eee18aaba34aa4457e680 100644 --- a/src/error.c +++ b/src/error.c @@ -109,8 +109,7 @@ void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn)) f_backtrace(0); f_aggregate(2); free_svalue(& throw_value); - sp--; - throw_value = *sp; + throw_value = *--sp; throw_severity=THROW_ERROR; in_error=0; diff --git a/src/modules/Oracle/oracle.c b/src/modules/Oracle/oracle.c index b8c18df4e1f0a729564b613c193a1c1ecabd2c45..e367447d96d40a8425833be6e0397db5ecfa99b7 100644 --- a/src/modules/Oracle/oracle.c +++ b/src/modules/Oracle/oracle.c @@ -1,5 +1,5 @@ /* - * $Id: oracle.c,v 1.6 1997/12/07 21:50:48 grubba Exp $ + * $Id: oracle.c,v 1.7 1998/01/30 06:20:21 hubbe Exp $ * * Pike interface to Oracle databases. * @@ -34,7 +34,7 @@ #endif -RCSID("$Id: oracle.c,v 1.6 1997/12/07 21:50:48 grubba Exp $"); +RCSID("$Id: oracle.c,v 1.7 1998/01/30 06:20:21 hubbe Exp $"); #ifdef HAVE_ORACLE @@ -585,6 +585,11 @@ void pike_module_init(void) void pike_module_exit(void) { #ifdef HAVE_ORACLE + if(oracle_program) + { + free_program(oracle_program); + oracle_program=0; + } if (oracle_result_program) { free_program(oracle_result_program); oracle_program = NULL; diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 585ef792101ba14890dfab4fcaf8168519747f95..9f73cd8cdbb5dc59b131ee04eb88fb4bd853cce8 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.71 1998/01/28 01:36:30 hubbe Exp $"); +RCSID("$Id: file.c,v 1.72 1998/01/30 06:20:54 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -1170,7 +1170,7 @@ static void file_pipe(INT32 args) int type=fd_CAN_NONBLOCK | fd_BIDIRECTIONAL; check_all_args("file->pipe",args, BIT_INT | BIT_VOID, 0); - if(args) type = sp[-args].u.integer;; + if(args) type = sp[-args].u.integer; do_close(FD,FILE_READ | FILE_WRITE); FD=-1; @@ -1602,6 +1602,97 @@ static void file_create(INT32 args) } } +#ifdef _REENTRANT + +struct new_thread_data +{ + struct object *from; + struct object *to; + INT32 fromfd, tofd; +}; + +static void *proxy_thread(void * data) +{ + char buffer[READ_BUFFER]; + struct new_thread_data *p=(struct new_thread_data *)data; + + while(1) + { + long len, w; + len=fd_read(p->fromfd, buffer, READ_BUFFER); + if(len<0) + { + if(errno==EINTR) continue; + break; + } + + w=0; + while(w<len) + { + long wl=fd_write(p->tofd, buffer+w, len-w); + if(wl<0) if(errno==EINTR) continue; + w+=wl; + } + } + + mt_lock(&interpreter_lock); + free_object(p->from); + free_object(p->to); + mt_unlock(&interpreter_lock); + free((char *)p); + return 0; +} + +void file_proxy(INT32 args) +{ + struct file_struct *f; + struct new_thread_data *p; + THREAD_T id; + check_all_args("Stdio.File->proxy",args, T_OBJECT,0); + f=(struct file_struct *)get_storage(sp[-args].u.object, file_program); + if(!f) + error("Bad argument 1 to Stdio.File->proxy, not a Stdio.File object.\n"); + + p=ALLOC_STRUCT(new_thread_data); + p->to=fp->current_object; + p->tofd=FD; + p->from=sp[-args].u.object; + p->fromfd=f->fd; + p->to->refs++; + p->from->refs++; + if(th_create_small(&id,new_thread_func,p)) + { + free((char *)p); + error("Failed to create thread.\n"); + } + th_destroy(& id); + pop_n_elems(args); + push_int(0); +} + +void create_proxy_pipe(struct object *o, int for_reading) +{ + struct object *n,*n2; + push_object(n=clone_object(file_program,0)); + push_int(fd_INTERPROCESSABLE); + apply(n,"pipe",1); + n2=sp[-1].u.object; + if(for_reading) + { + ref_push_object(o); + apply(n2,"proxy",1); + pop_n_elems(2); + }else{ + /* Swap */ + sp[-2].u.object=n2; + sp[-1].u.object=n; + apply(o,"proxy",1); + pop_stack(); + } +} + +#endif + void pike_module_exit(void) { if(file_program) @@ -1717,6 +1808,9 @@ void pike_module_init(void) add_function("create",file_create,"function(void|string,void|string:void)",0); add_function("`<<",file_lsh,"function(mixed:object)",0); +#ifdef _REENTRANT + add_function("proxy",file_proxy,"function(object:void)",0); +#endif set_init_callback(init_file_struct); set_exit_callback(exit_file_struct); set_gc_mark_callback(gc_mark_file_struct); diff --git a/src/modules/system/system.c b/src/modules/system/system.c index e449f02a87a29e43afd69a491d5c2d64f67358ca..6081b3f5d1d19c59d12529e11a268dc4b9a2963d 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $ + * $Id: system.c,v 1.40 1998/01/30 06:21:37 hubbe Exp $ * * System-call module for Pike * @@ -14,7 +14,7 @@ #include "system.h" #include "global.h" -RCSID("$Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $"); +RCSID("$Id: system.c,v 1.40 1998/01/30 06:21:37 hubbe Exp $"); #ifdef HAVE_WINSOCK2_H #include <winsock2.h> #endif @@ -873,7 +873,6 @@ static void f_cp(INT32 args) } #endif - /* * Module linkage */ diff --git a/src/signal_handler.c b/src/signal_handler.c index 3fa42e4bfaa06256cb6f7c2fd5c6a868fdc63e35..cd7a10021d5c2ea4c7aaa379fecb6b66e05ee660 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -429,7 +429,10 @@ static void report_child(int pid, pid_status_program))) { p->state = PROCESS_EXITED; - p->result = WEXITSTATUS(status); + if(WIFEXITED(p->result)) + p->result = WEXITSTATUS(status); + else + p->result=-1; } } map_delete(pid_mapping, &key); @@ -538,9 +541,12 @@ static TCHAR *convert_string(char *str, int len) return ret; } -static HANDLE get_inheritable_handle(struct mapping *optional, char *name) +static HANDLE get_inheritable_handle(struct mapping *optional, + char *name, + int for_reading) { HANDLE ret=INVALID_HANDLE_VALUE; + struct svalue *save_stack=sp; struct svalue *tmp; if((tmp=simple_mapping_string_lookup(optional, name))) { @@ -549,6 +555,15 @@ static HANDLE get_inheritable_handle(struct mapping *optional, char *name) apply(tmp->u.object,"query_fd",0); if(sp[-1].type == T_INT) { + if(!(fd_query_properties(sp[-1].u.integer) & fd_INTERPROCESSABLE)) + { + void create_proxy_pipe(struct object *o, int for_reading); + + create_proxy_pipe(tmp->u.object, for_reading); + apply(sp[-1].u.object, "query_fd", 0); + } + + if(!DuplicateHandle(GetCurrentProcess(), (HANDLE)da_handle[sp[-1].u.integer], GetCurrentProcess(), @@ -559,9 +574,9 @@ static HANDLE get_inheritable_handle(struct mapping *optional, char *name) /* This could cause handle-leaks */ error("Failed to duplicate handle %d.\n",GetLastError()); } - pop_stack(); } } + pop_n_elems(sp-save_stack); return ret; } #endif @@ -654,13 +669,13 @@ void f_create_process(INT32 args) if(tmp->type == T_STRING) dir=convert_string(tmp->u.string->str, tmp->u.string->len); - t1=get_inheritable_handle(optional, "stdin"); + t1=get_inheritable_handle(optional, "stdin",0); if(t1!=INVALID_HANDLE_VALUE) info.hStdInput=t1; - t2=get_inheritable_handle(optional, "stdout"); + t2=get_inheritable_handle(optional, "stdout",1); if(t2!=INVALID_HANDLE_VALUE) info.hStdOutput=t2; - t3=get_inheritable_handle(optional, "stderr"); + t3=get_inheritable_handle(optional, "stderr",1); if(t3!=INVALID_HANDLE_VALUE) info.hStdError=t3; if((tmp=simple_mapping_string_lookup(optional, "env"))) diff --git a/src/threads.c b/src/threads.c index 27bb72474629d3d46c7891ab0fb3f4811a4a43b3..73e292ca0378f5730210d90899597b47d44cd624 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.54 1998/01/26 20:00:01 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.55 1998/01/30 06:19:51 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -143,6 +143,7 @@ struct program *mutex_key = 0; struct program *thread_id_prog = 0; #ifdef POSIX_THREADS pthread_attr_t pattr; +pthread_attr_t small_pattr; #endif struct thread_starter @@ -607,6 +608,13 @@ void th_init(void) pthread_attr_setstacksize(&pattr, 2 * 1024 * 1204); #endif pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); + + pthread_attr_init(&small_pattr); +#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE + pthread_attr_setstacksize(&small_pattr, 32768); +#endif + pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED); + #endif add_efun("thread_create",f_thread_create,"function(mixed ...:object)", diff --git a/src/threads.h b/src/threads.h index 2379a3088402db7c4590b550f86f25ab1dcc8a5e..45c9acd14331082d4e5660907e15945aff83f5fe 100644 --- a/src/threads.h +++ b/src/threads.h @@ -70,8 +70,11 @@ extern struct object *thread_id; #else #define th_yield() #endif /* HAVE_PTHREAD_YIELD */ +extern pthread_attr_t pattr; +extern pthread_attr_t small_pattr; #define th_create(ID,fun,arg) pthread_create(ID,&pattr,fun,arg) +#define th_create_small(ID,fun,arg) pthread_create(ID,&small_pattr,fun,arg) #define th_exit(foo) pthread_exit(foo) #define th_self() pthread_self() @@ -110,6 +113,7 @@ extern struct object *thread_id; #define th_setconcurrency(X) thr_setconcurrency(X) #define th_create(ID,fun,arg) thr_create(NULL,0,fun,arg,THR_DAEMON,ID) +#define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON,ID) #define th_exit(foo) thr_exit(foo) #define th_self() thr_self() #define th_yield() thr_yield() @@ -141,6 +145,7 @@ extern struct object *thread_id; #define PIKE_SPROC_FLAGS (PR_SADDR|PR_SFDS|PR_SDIR|PS_SETEXITSIG) #define th_create(ID, fun, arg) (((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1) +#define th_create_small(ID, fun, arg) (((*(ID)) = sproc(fun, PIKE_SPROC_FLAGS, arg)) == -1) #define th_exit(X) exit(X) #define th_self() getpid() #define th_yield() sginap(0) @@ -159,6 +164,7 @@ extern struct object *thread_id; #define THREAD_T HANDLE #define th_setconcurrency(X) #define th_create(ID,fun,arg) (!(*(ID)=_beginthread(fun, 2*1024*1024, arg))) +#define th_create_small(ID,fun,arg) (!(*(ID)=_beginthread(fun, 32768, arg))) #define th_exit(foo) _endthread(foo) #define th_self() GetCurrentThread() #define th_destroy(X)