expander: repair a race condition related to "available" modules

Fix a broken use of a lock intended to prevent threads from
conflicting while forcing "available" modules to "visited" module.
This commit is contained in:
Matthew Flatt 2018-07-18 10:42:27 -06:00
parent d3a5006721
commit 49a90ba75e
3 changed files with 31 additions and 5 deletions

View File

@ -2736,6 +2736,32 @@ case of module-leve bindings; it doesn't cover local bindings.
(dynamic-require '(submod 'm check) #f)
(eval 'x (module->namespace '(submod 'm check))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Try to provoke race conditions in the expander related
;; to instanitiating compile-time instances on demand
(test #t
'no-races-found
(for/and ([i (in-range 100)])
(let ([ok? #t]
[work 0])
(for-each
sync
(parameterize ([current-namespace (make-base-namespace)])
(for/list ([i 5])
(thread
(lambda ()
;; "make work" to try to trigger a thread swap during `expand`
(for ([w (in-range (random 1000))])
(set! work (add1 work)))
(with-handlers ([exn? (lambda (exn)
(set! ok? #f)
(raise exn))])
;; This `expand` will force compile-time instances of
;; various modules used by `racket/base`
(expand `(lambda (x) x))))))))
ok?)))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -502,9 +502,9 @@
(let loop ()
(define mis (hash-ref (namespace-available-module-instances ns) run-phase null))
(unless (null? mis)
(hash-set! (namespace-available-module-instances ns) run-phase null)
(for ([mi (in-list (reverse mis))])
(run-module-instance! mi ns #:run-phase run-phase #:skip-run? #f #:otherwise-available? #f))
(hash-set! (namespace-available-module-instances ns) run-phase null)
;; In case instantiation added more reflectively:
(loop)))))))

View File

@ -14019,10 +14019,6 @@ static const char *startup_source =
"(void)"
"(let-values()"
"(begin"
"(hash-set!"
"(namespace-available-module-instances ns_37)"
" run-phase_4"
" null)"
"(let-values(((lst_67)(reverse$1 mis_0)))"
"(begin"
"(if(variable-reference-from-unsafe?"
@ -14072,6 +14068,10 @@ static const char *startup_source =
" for-loop_91)"
" lst_67)))"
"(void)"
"(hash-set!"
"(namespace-available-module-instances ns_37)"
" run-phase_4"
" null)"
"(loop_77)))))))))"
" loop_77)))))))))))))"
"(case-lambda"