diff --git a/pkgs/racket-test-core/tests/racket/sync.rktl b/pkgs/racket-test-core/tests/racket/sync.rktl index 44f0df8250..d596336b8e 100644 --- a/pkgs/racket-test-core/tests/racket/sync.rktl +++ b/pkgs/racket-test-core/tests/racket/sync.rktl @@ -1235,7 +1235,8 @@ should-post-break? should-done-break?) ;; print the state for this test: - (test #t list? (list 'go + (test #t list? (list 'go + mk-t* break-off? pre-thunk act-thunk post-thunk pre-semaphore-wait act-semaphore-wait post-semaphore-wait try-pre-break @@ -1354,8 +1355,8 @@ no-capture no-capture no-capture args))))]) (list plain-mk-t - (mk-capturing 'pre) - (mk-capturing 'act)))))) + (procedure-rename (mk-capturing 'pre) 'pre-capturing) + (procedure-rename (mk-capturing 'act) 'act-capturing)))))) ;; ---------------------------------------- ;; Check wrap-evt result superceded by internally diff --git a/pkgs/racket-test-core/tests/racket/thread.rktl b/pkgs/racket-test-core/tests/racket/thread.rktl index db05abb525..6280a39b0d 100644 --- a/pkgs/racket-test-core/tests/racket/thread.rktl +++ b/pkgs/racket-test-core/tests/racket/thread.rktl @@ -197,6 +197,49 @@ (err/rt-test (break-thread (current-thread) 'hang-up) exn:break:hang-up?) (err/rt-test (break-thread (current-thread) 'terminate) exn:break:terminate?) +(let ([bad? #f]) + (define t + (thread + (lambda () + (let/ec k + (parameterize-break #f + (break-thread (current-thread)) + (k #f))) + (set! bad? #t)))) + (sync t) + (test #f 'escape bad?)) + +(let ([bad? #f]) + (define t + (thread + (lambda () + (let/cc k + (parameterize-break #f + (break-thread (current-thread)) + (k #f))) + (set! bad? #t)))) + (sync t) + (test #f 'escape/cc bad?)) + +(let ([bad? #f]) + (define t + (thread + (lambda () + (define jump-k #f) + (parameterize-break #f + ((let/cc k + (set! jump-k k) + void) + #f)) + (let/cc k + (parameterize-break #f + (break-thread (current-thread)) + (jump-k k))) + (set! bad? #t)))) + (sync t) + (test #f 'jump-in bad?)) + + (let ([ex? #f] [s (make-semaphore)]) (define (go) diff --git a/racket/src/cs/rumble/control.ss b/racket/src/cs/rumble/control.ss index e60c78f150..e83fbd10fd 100644 --- a/racket/src/cs/rumble/control.ss +++ b/racket/src/cs/rumble/control.ss @@ -286,7 +286,7 @@ [(aborting? r) ;; Remove the prompt as we call the handler: (pop-metacontinuation-frame) - (end-uninterrupted 'handle) + (end-uninterrupted/call-hook 'handle) (apply handler (aborting-args r))] [else @@ -888,11 +888,7 @@ ;; Called on the arguments to return to a continuation ;; captured by `call/cc/end-uninterrupted`: (define (end-uninterrupted-with-values args) - ;; Arguably, we should use `end-uninterrupted/hook` here to check - ;; for breaks, in case a jump enabled breaks and one is pending. - ;; The traditional Racket implementation doesn't include that - ;; check, and the check imposes a costs, so we leave it out for now. - (end-uninterrupted 'cc) + (end-uninterrupted/call-hook 'cc) (apply values args)) (define (current-mark-chain) diff --git a/racket/src/racket/src/fun.c b/racket/src/racket/src/fun.c index 6d68267368..3cf5226a5d 100644 --- a/racket/src/racket/src/fun.c +++ b/racket/src/racket/src/fun.c @@ -4276,6 +4276,7 @@ do_call_ec (int argc, Scheme_Object *argv[], Scheme_Object *_for_cc) reset_cjs(&p2->cjs); scheme_restore_env_stack_w_thread(cont->envss, p2); p2->suspend_break = 0; + scheme_check_break_now(); if (n != 1) v = scheme_values(n, (Scheme_Object **)v); } else { diff --git a/racket/src/thread/thread.rkt b/racket/src/thread/thread.rkt index 51802079bc..52ef943650 100644 --- a/racket/src/thread/thread.rkt +++ b/racket/src/thread/thread.rkt @@ -725,7 +725,11 @@ ;; `check-for-break` should be called. (define (check-for-break) (define t (current-thread)) - (when t ; allow `check-for-break` before threads are running + (when (and + ;; allow `check-for-break` before threads are running: + t + ;; quick pre-test before going atomic: + (thread-pending-break t)) ((atomically (cond [(and (thread-pending-break t)