From d3f2bd6dace0005d22f2feefe4ad5edfa1408d9d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 15 Nov 2015 16:46:07 -0700 Subject: [PATCH] fix broken abort handling related to module-registry lock --- .../racket-test-core/tests/racket/module.rktl | 28 +++++++++++++++++++ racket/src/racket/src/module.c | 17 +++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 1be29de2c8..dab843cf3f 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -1642,6 +1642,34 @@ case of module-leve bindings; it doesn't cover local bindings. (#%require (submod ".." ma)) (foo))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure that shutting down a custodian +;; releases a lock as it should + +(parameterize ([current-custodian (make-custodian)]) + (thread-wait + (thread + (lambda () + (parameterize ([current-namespace (make-base-namespace)]) + (eval '(module m racket/base + (require (for-syntax racket/base)) + (begin-for-syntax + #;(log-error "nested") + ;; Using an environment variable to communicate across phases: + (when (getenv "PLT_ready_to_end") + #;(log-error "adios") + (custodian-shutdown-all (current-custodian)))))) + (eval '(module n racket/base + (require (for-syntax racket/base)) + (begin-for-syntax + #;(log-error "outer") + (dynamic-require ''m 0) + (eval #f)))) + (putenv "PLT_ready_to_end" "yes") + (dynamic-require ''n 0) + #;(log-error "go") + (eval #f)))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/racket/src/module.c b/racket/src/racket/src/module.c index cdda0b464c..238f0d266d 100644 --- a/racket/src/racket/src/module.c +++ b/racket/src/racket/src/module.c @@ -4932,9 +4932,11 @@ static void lock_registry(Scheme_Env *env) static void unlock_registry(Scheme_Env *env) { Scheme_Object *lock; - lock = scheme_hash_get(env->module_registry->loaded, scheme_false); - scheme_post_sema(SCHEME_CAR(lock)); - scheme_hash_set(env->module_registry->loaded, scheme_false, NULL); + if (env) { + lock = scheme_hash_get(env->module_registry->loaded, scheme_false); + scheme_post_sema(SCHEME_CAR(lock)); + scheme_hash_set(env->module_registry->loaded, scheme_false, NULL); + } } XFORM_NONGCING static intptr_t make_key(int base_phase, int eval_exp, int eval_run) @@ -5742,7 +5744,7 @@ static void start_module(Scheme_Module *m, Scheme_Env *env, int restart, static void do_prepare_compile_env(Scheme_Env *env, int base_phase, int pos) { Scheme_Object *v, *prev; - Scheme_Env *menv; + Scheme_Env *menv, *uenv; int need_lock; need_lock = wait_registry(env); @@ -5763,14 +5765,17 @@ static void do_prepare_compile_env(Scheme_Env *env, int base_phase, int pos) } v = prev; - if (need_lock) + if (need_lock) { lock_registry(env); + uenv = env; + } else + uenv = NULL; while (SCHEME_NAMESPACEP(v)) { menv = (Scheme_Env *)v; v = menv->available_next[pos]; menv->available_next[pos] = NULL; - BEGIN_ESCAPEABLE(unlock_registry, env); + BEGIN_ESCAPEABLE(unlock_registry, uenv); start_module(menv->module, menv->instance_env, 0, NULL, 1, 0, base_phase, scheme_null, 1);