racket-ssh-2012/blocking-box.rkt

39 lines
1.1 KiB
Racket
Raw Normal View History

2011-10-22 13:20:54 +00:00
#lang racket/base
;; A box whose value can only be set once, that starts life with no
;; value, and that supports an event waiting for a value to arrive.
(provide make-blocking-box
blocking-box-evt
blocking-box-value
set-blocking-box!)
2011-10-22 16:00:21 +00:00
(struct blocking-box (thread set-ch get-ch))
2011-10-22 13:20:54 +00:00
(define (make-blocking-box)
2011-10-22 16:00:21 +00:00
(define set-ch (make-channel))
(define get-ch (make-channel))
(blocking-box (thread/suspend-to-kill (lambda () (manager set-ch get-ch)))
set-ch
get-ch))
(define (manager s g)
(define v (channel-get s))
(let loop ()
2011-11-23 20:50:56 +00:00
(sync s (channel-put-evt g v)) ;; ignore any future settings, answer all future gettings
(loop)))
2011-10-22 13:20:54 +00:00
(define (blocking-box-evt b)
2011-10-22 16:00:21 +00:00
(guard-evt
(lambda ()
;; Ensure the manager is running within our custodian:
(thread-resume (blocking-box-thread b) (current-thread))
(blocking-box-get-ch b))))
2011-10-22 13:20:54 +00:00
(define (blocking-box-value b)
(sync (blocking-box-evt b)))
(define (set-blocking-box! b v)
2011-10-22 16:00:21 +00:00
;; Ensure the manager is running within our custodian:
(thread-resume (blocking-box-thread b) (current-thread))
(channel-put (blocking-box-set-ch b) v))