thread: fix atomic-timeout-callback implementation

Closes racket/drracket#238
This commit is contained in:
Matthew Flatt 2018-11-14 16:44:01 -07:00
parent cf34c22380
commit bf7eee0f65
4 changed files with 43 additions and 4 deletions

View File

@ -0,0 +1,21 @@
#lang racket/base
(require ffi/unsafe/try-atomic)
(define ch (make-channel))
(define done? #f)
(define (check v expect)
(unless (equal? v expect)
(error 'check "failed: ~s vs. ~s" v expect)))
(check
(call-as-nonatomic-retry-point
(lambda ()
(try-atomic
(lambda ()
(sync/timeout 0.25 ch)
(set! done? #t))
'no)))
'no)
(check done? #t)

View File

@ -19,7 +19,8 @@ GLOBALS = --no-global \
++global-ok the-sandman \ ++global-ok the-sandman \
++global-ok sync-on-channel \ ++global-ok sync-on-channel \
++global-ok post-shutdown-action \ ++global-ok post-shutdown-action \
++global-ok get-subprocesses-time ++global-ok get-subprocesses-time \
++global-ok force-atomic-timeout-callback
GENERATE_ARGS = -t main.rkt --submod main \ GENERATE_ARGS = -t main.rkt --submod main \
--check-depends $(BUILDDIR)compiled/thread-dep.rktd \ --check-depends $(BUILDDIR)compiled/thread-dep.rktd \

View File

@ -82,7 +82,7 @@
(check-for-break) (check-for-break)
(when atomic-timeout-callback (when atomic-timeout-callback
(when (positive? (current-atomic)) (when (positive? (current-atomic))
(atomic-timeout-callback)))) (atomic-timeout-callback #f))))
(lambda args (lambda args
(start-implicit-atomic-mode) (start-implicit-atomic-mode)
(accum-cpu-time! t) (accum-cpu-time! t)
@ -235,6 +235,14 @@
atomic-timeout-callback atomic-timeout-callback
(set! atomic-timeout-callback cb))) (set! atomic-timeout-callback cb)))
(void (set-force-atomic-timeout-callback!
(lambda ()
(and atomic-timeout-callback
(begin
(atomic-timeout-callback #t)
#t)))))
;; ---------------------------------------- ;; ----------------------------------------
(define check-place-activity void) (define check-place-activity void)

View File

@ -82,6 +82,8 @@
check-for-break check-for-break
current-break-suspend current-break-suspend
set-force-atomic-timeout-callback!
break-max)) break-max))
;; Exports needed by "place.rkt": ;; Exports needed by "place.rkt":
@ -387,6 +389,10 @@
(define sleeping (sandman-add-sleeping-thread! t ext-events)) (define sleeping (sandman-add-sleeping-thread! t ext-events))
(set-thread-sleeping! t sleeping)) (set-thread-sleeping! t sleeping))
(define force-atomic-timeout-callback void)
(define (set-force-atomic-timeout-callback! proc)
(set! force-atomic-timeout-callback proc))
;; in atomic mode ;; in atomic mode
;; Removes a thread from its thread group, so it won't be scheduled; ;; Removes a thread from its thread group, so it won't be scheduled;
;; returns a thunk to be called in out of atomic mode to swap out the ;; returns a thunk to be called in out of atomic mode to swap out the
@ -405,8 +411,11 @@
;; by a custodian callback ;; by a custodian callback
(lambda () (lambda ()
(when (eq? t (current-thread)) (when (eq? t (current-thread))
(when (positive? (current-atomic)) (let loop ()
(internal-error "attempt to deschedule the current thread in atomic mode")) (when (positive? (current-atomic))
(if (force-atomic-timeout-callback)
(loop)
(internal-error "attempt to deschedule the current thread in atomic mode"))))
(engine-block) (engine-block)
(check-for-break)))) (check-for-break))))