diff --git a/src/encode.c b/src/encode.c index 31f100aeb97e3b43fc820ae8398cbb4f7070b9db..03355c4ec479fbc02ef5d2f8963f106f930d0c79 100644 --- a/src/encode.c +++ b/src/encode.c @@ -307,13 +307,6 @@ static void code_number(ptrdiff_t num, struct encode_data *data) num >> 4, data); } -#ifdef _REENTRANT -static void do_enable_threads(void) -{ - exit_threads_disable(NULL); -} -#endif - /* NOTE: Take care to encode it exactly as the corresponing * type string would have been encoded (cf T_FUNCTION, T_MANY, * T_STRING, PIKE_T_NSTRING). @@ -3270,13 +3263,10 @@ static void decode_value2(struct decode_data *data) char *dat=0; struct program *p; struct object *placeholder=0; - ONERROR err1, err2, err3, err4; + ONERROR err, err1, err2, err3, err4; -#ifdef _REENTRANT - ONERROR err; - low_init_threads_disable(); - SET_ONERROR(err, do_enable_threads, 0); -#endif + lock_pike_compiler(); + SET_ONERROR(err, unlock_pike_compiler, 0); fprintf (stderr, "Warning: Using old-style encoding\n"); @@ -3883,10 +3873,7 @@ static void decode_value2(struct decode_data *data) } } -#ifdef _REENTRANT - UNSET_ONERROR(err); - exit_threads_disable(NULL); -#endif + CALL_AND_UNSET_ONERROR(err); goto decode_done; } diff --git a/src/pike_compiler.h b/src/pike_compiler.h index 050ffb210442b5d60342584773ba3618568a55a6..7578586af69346705d030d701186f9c9170a1179 100644 --- a/src/pike_compiler.h +++ b/src/pike_compiler.h @@ -34,7 +34,7 @@ struct compilation int compilation_depth; /* Current class nesting depth. */ #ifdef PIKE_THREADS - int saved_threads_disabled; + int saved_lock_depth; #endif struct mapping *resolve_cache; }; diff --git a/src/program.c b/src/program.c index 0fc854ce22cd9f22101f0662107c044963d78c45..768488a8a2e4b5bf96bce4b1d77fc47432e5202e 100644 --- a/src/program.c +++ b/src/program.c @@ -47,6 +47,39 @@ #undef ATTRIBUTE #define ATTRIBUTE(X) +#ifdef PIKE_THREADS +static COND_T Pike_compiler_cond; +static THREAD_T Pike_compiler_thread; +static int lock_depth = 0; + +PMOD_EXPORT void lock_pike_compiler(void) +{ + while (lock_depth && (Pike_compiler_thread != th_self())) { + co_wait_interpreter(&Pike_compiler_cond); + } + lock_depth++; + Pike_compiler_thread = th_self(); +} + +PMOD_EXPORT void unlock_pike_compiler(void) +{ +#ifdef PIKE_DEBUG + if (lock_depth < 1) { + Pike_fatal("Pike compiler running unlocked!\n"); + } +#endif + lock_depth--; + co_broadcast(&Pike_compiler_cond); +} +#else +PMOD_EXPORT void lock_pike_compiler(void) +{ +} +PMOD_EXPORT void unlock_pike_compiler(void) +{ +} +#endif + static void low_enter_compiler(struct object *ce, int inherit); static void exit_program_struct(struct program *); static size_t add_xstorage(size_t size, @@ -85,8 +118,8 @@ void free_all_program_blocks() { #ifdef COMPILER_DEBUG #define CDFPRINTF(X) fprintf X #ifndef PIKE_THREADS -/* The CDFPRINTF lines wants to print threads_disabled, so fake on of those */ -static const int threads_disabled = 1; +/* The CDFPRINTF lines wants to print lock_depth, so fake one of those */ +static const int lock_depth = 1; #endif #else /* !COMPILER_DEBUG */ #define CDFPRINTF(X) @@ -2845,10 +2878,11 @@ void low_start_new_program(struct program *p, CHECK_COMPILER(); - /* We don't want to change thread, but we don't want to - * wait for the other threads to complete either. + /* We aren't thread safe, but we are reentrant. + * + * Lock out any other threads from the compiler until we are finished. */ - low_init_threads_disable(); + lock_pike_compiler(); c->compilation_depth++; @@ -2893,10 +2927,10 @@ void low_start_new_program(struct program *p, if(idp) *idp=id; CDFPRINTF((stderr, "th(%ld) %p low_start_new_program() %s " - "pass=%d: threads_disabled:%d, compilation_depth:%d\n", + "pass=%d: lock_depth:%d, compilation_depth:%d\n", (long)th_self(), p, name ? name->str : "-", Pike_compiler->compiler_pass, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); init_type_stack(); @@ -3126,9 +3160,9 @@ PMOD_EXPORT void debug_start_new_program(INT_TYPE line, const char *file) CDFPRINTF((stderr, "th(%ld) start_new_program(%ld, %s): " - "threads_disabled:%d, compilation_depth:%d\n", + "lock_depth:%d, compilation_depth:%d\n", (long)th_self(), (long)line, file, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); low_start_new_program(0,1,0,0,0); store_linenumber(line,c->lex.current_file); @@ -4152,13 +4186,13 @@ struct program *end_first_pass(int finish) CDFPRINTF((stderr, "th(%ld) %p end_first_pass(%d): " - "threads_disabled:%d, compilation_depth:%d\n", + "lock_depth:%d, compilation_depth:%d\n", (long)th_self(), prog, finish, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); c->compilation_depth--; - exit_threads_disable(NULL); + unlock_pike_compiler(); #if 0 #ifdef PIKE_USE_MACHINE_CODE @@ -8986,9 +9020,9 @@ static int run_pass1(struct compilation *c) CDFPRINTF((stderr, "th(%ld) %p run_pass1() start: " - "threads_disabled:%d, compilation_depth:%d\n", + "lock_depth:%d, compilation_depth:%d\n", (long)th_self(), Pike_compiler->new_program, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); run_init2(c); @@ -9075,9 +9109,9 @@ void run_pass2(struct compilation *c) CDFPRINTF((stderr, "th(%ld) %p run_pass2() start: " - "threads_disabled:%d, compilation_depth:%d\n", + "lock_depth:%d, compilation_depth:%d\n", (long)th_self(), Pike_compiler->new_program, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); verify_supporters(); @@ -9100,20 +9134,20 @@ static void run_cleanup(struct compilation *c, int delayed) debug_malloc_touch(c->placeholder); #if 0 /* FIXME */ #ifdef PIKE_THREADS - if (threads_disabled != c->saved_threads_disabled) { - Pike_fatal("compile(): threads_disabled:%d saved_threads_disabled:%d\n", - threads_disabled, c->saved_threads_disabled); + if (lock_depth != c->saved_lock_depth) { + Pike_fatal("compile(): lock_depth:%d saved_lock_depth:%d\n", + lock_depth, c->saved_lock_depth); } #endif #endif /* PIKE_DEBUG */ - exit_threads_disable(NULL); + unlock_pike_compiler(); CDFPRINTF((stderr, "th(%ld) %p run_cleanup(): " - "threads_disabled:%d, compilation_depth:%d\n", + "lock_depth:%d, compilation_depth:%d\n", (long)th_self(), c->target, - threads_disabled, c->compilation_depth)); + lock_depth, c->compilation_depth)); if (!c->p) { /* fprintf(stderr, "Destructing placeholder.\n"); */ @@ -9564,9 +9598,9 @@ static void f_compilation_compile(INT32 args) c->flags |= COMPILER_BUSY; - low_init_threads_disable(); + lock_pike_compiler(); #ifdef PIKE_THREADS - c->saved_threads_disabled = threads_disabled; + c->saved_lock_depth = lock_depth; #endif init_supporter(& c->supporter, @@ -10524,9 +10558,9 @@ struct program *compile(struct pike_string *aprog, SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n"); #endif - low_init_threads_disable(); + lock_pike_compiler(); #ifdef PIKE_THREADS - c->saved_threads_disabled = threads_disabled; + c->saved_lock_depth = lock_depth; #endif init_supporter(& c->supporter, @@ -10840,6 +10874,10 @@ void init_program(void) lfun_getter_type_string = make_pike_type(tFuncV(tNone, tVoid, tMix)); lfun_setter_type_string = make_pike_type(tFuncV(tZero, tVoid, tVoid)); +#ifdef PIKE_THREADS + co_init(&Pike_compiler_cond); +#endif + compile_compiler(); enter_compiler(NULL, 0); @@ -10967,6 +11005,9 @@ void cleanup_program(void) free_program(reporter_program); reporter_program = 0; } +#ifdef PIKE_THREADS + co_destroy(&Pike_compiler_cond); +#endif } diff --git a/src/program.h b/src/program.h index b4662b99ac78dbd5b46462b6f64fe7f933ad825b..ad084efa94aa3463cf059bc13255418ff24ebc08 100644 --- a/src/program.h +++ b/src/program.h @@ -769,6 +769,8 @@ struct Supporter }; /* Prototypes begin here */ +PMOD_EXPORT void lock_pike_compiler(void); +PMOD_EXPORT void unlock_pike_compiler(void); PMOD_EXPORT void do_free_program (struct program *p); void ins_int(INT32 i, void (*func)(char tmp)); void ins_short(int i, void (*func)(char tmp));