diff --git a/pkgs/racket-pkgs/racket-test/tests/racket/place-kill-unwind.rkt b/pkgs/racket-pkgs/racket-test/tests/racket/place-kill-unwind.rkt new file mode 100644 index 0000000000..c06950267d --- /dev/null +++ b/pkgs/racket-pkgs/racket-test/tests/racket/place-kill-unwind.rkt @@ -0,0 +1,26 @@ +#lang racket/base +(require racket/place) + +;; When a thread is killed during `directory-list`, there's +;; a clean-up action attached to both the thread and its +;; `dynamic-wind` chain (effectively). Check that only one +;; of them runs, otherwise closedir() is called twice (and +;; libc will typically detect a mistake and abort). + +(define (go) + (place + pch + (place-channel-put pch 'ok) + (let loop () + (directory-list + (let-values ([(base name dir?) + (split-path (collection-file-path "place.rkt" "racket"))]) + base)) + (loop)))) + +(module+ main + (for ([i 25]) + (printf "~a\n" i) + (define p (go)) + (place-channel-get p) + (place-kill p))) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index cdf7ec09df..71f7bc0823 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -4371,7 +4371,7 @@ static void escape_to_kill(Scheme_Thread *p) p->cjs.jumping_to_continuation = (Scheme_Object *)p; p->cjs.alt_full_continuation = NULL; p->cjs.is_kill = 1; - p->cjs.skip_dws = 0; + p->cjs.skip_dws = 1; scheme_longjmp(*p->error_buf, 1); }