Skip to content

Commit

Permalink
cs & thread: repair thread-break on terminated thread
Browse files Browse the repository at this point in the history
The `threadbreak` function should not try to reschedule a terminated
thread.

Thanks to Daniel Holtby for the report and text case.
  • Loading branch information
mflatt committed Jul 13, 2021
1 parent 6a65e37 commit 9f2cbab
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
12 changes: 12 additions & 0 deletions pkgs/racket-test-core/tests/racket/thread.rktl
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,18 @@
(test #t integer? (current-process-milliseconds 'subprocesses))
(err/rt-test (current-process-milliseconds 'other))

;; --------------------
;; Check `thread-break` on a thread kiled while it tried to sync:

(let ()
(define t (thread (lambda () (sync never-evt))))
(sync (system-idle-evt))
(kill-thread t)
(test #t thread-dead? t)
(sync (system-idle-evt))
(test (void) break-thread t)
(test #t thread-dead? t))

; --------------------

(report-errs)
48 changes: 25 additions & 23 deletions racket/src/cs/schemified/thread.scm
Original file line number Diff line number Diff line change
Expand Up @@ -7886,30 +7886,32 @@
(begin
(start-atomic)
(begin0
(let ((c1_0 (thread-forward-break-to t_0)))
(if c1_0
(lambda () (do-break-thread c1_0 kind_0 check-t_0))
(begin
(if (if (thread-pending-break t_0)
(break>? kind_0 (thread-pending-break t_0))
#f)
(set-thread-pending-break! t_0 kind_0)
(void))
(if (thread-pending-break t_0)
(void)
(begin
(if (1/thread-dead? t_0)
void
(let ((c1_0 (thread-forward-break-to t_0)))
(if c1_0
(lambda () (do-break-thread c1_0 kind_0 check-t_0))
(begin
(if (if (thread-pending-break t_0)
(break>? kind_0 (thread-pending-break t_0))
#f)
(set-thread-pending-break! t_0 kind_0)
(thread-did-work!)
(run-suspend/resume-callbacks t_0 car)
(run-suspend/resume-callbacks t_0 cdr)
(if (thread-descheduled? t_0)
(if (thread-suspended? t_0)
(void)
(begin
(run-interrupt-callback t_0)
(thread-reschedule! t_0)))
(void))))
void)))
(void))
(if (thread-pending-break t_0)
(void)
(begin
(set-thread-pending-break! t_0 kind_0)
(thread-did-work!)
(run-suspend/resume-callbacks t_0 car)
(run-suspend/resume-callbacks t_0 cdr)
(if (thread-descheduled? t_0)
(if (thread-suspended? t_0)
(void)
(begin
(run-interrupt-callback t_0)
(thread-reschedule! t_0)))
(void))))
void))))
(end-atomic))))
(if (eq? t_0 check-t_0)
(begin
Expand Down
1 change: 1 addition & 0 deletions racket/src/thread/thread.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@
(define (do-break-thread t kind check-t)
((atomically
(cond
[(thread-dead? t) void]
[(thread-forward-break-to t)
=> (lambda (other-t)
(lambda () (do-break-thread other-t kind check-t)))]
Expand Down

0 comments on commit 9f2cbab

Please sign in to comment.