mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-18 21:29:19 +02:00
44 lines
1.4 KiB
Scheme
44 lines
1.4 KiB
Scheme
;; channel.scm -- thread-safe channel (FIFO) library
|
|
;; Copyright (c) 2012 Alex Shinn. All rights reserved.
|
|
;; BSD-style license: http://synthcode.com/license.txt
|
|
|
|
(define-record-type Channel
|
|
(%make-channel mutex condvar front rear)
|
|
channel?
|
|
(mutex channel-mutex channel-mutex-set!)
|
|
(condvar channel-condvar channel-condvar-set!)
|
|
(front channel-front channel-front-set!)
|
|
(rear channel-rear channel-rear-set!))
|
|
|
|
(define (make-channel)
|
|
(%make-channel (make-mutex) (make-condition-variable) '() '()))
|
|
|
|
(define (channel-empty? chan)
|
|
(null? (channel-front chan)))
|
|
|
|
(define (channel-send! chan obj)
|
|
(mutex-lock! (channel-mutex chan))
|
|
(let ((new (list obj))
|
|
(rear (channel-rear chan)))
|
|
(channel-rear-set! chan new)
|
|
(cond
|
|
((pair? rear)
|
|
(set-cdr! rear new))
|
|
(else ; sending to empty channel
|
|
(channel-front-set! chan new)
|
|
(condition-variable-broadcast! (channel-condvar chan)))))
|
|
(mutex-unlock! (channel-mutex chan)))
|
|
|
|
(define (channel-receive! chan)
|
|
(mutex-lock! (channel-mutex chan))
|
|
(let ((front (channel-front chan)))
|
|
(cond
|
|
((null? front) ; receiving from empty channel
|
|
(mutex-unlock! (channel-mutex chan) (channel-condvar chan))
|
|
(channel-receive! chan))
|
|
(else
|
|
(channel-front-set! chan (cdr front))
|
|
(if (null? (cdr front))
|
|
(channel-rear-set! chan '()))
|
|
(mutex-unlock! (channel-mutex chan))
|
|
(car front)))))
|