Adding channels (i.e. mailboxes, i.e. thread-safe queues) for easy coordination between threads.

This commit is contained in:
Alex Shinn 2012-05-13 14:30:25 +09:00
parent 1aff449a48
commit 3fdf435ba3
2 changed files with 50 additions and 0 deletions

44
lib/chibi/channel.scm Normal file
View file

@ -0,0 +1,44 @@
;; 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-signal! (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)))))

6
lib/chibi/channel.sld Normal file
View file

@ -0,0 +1,6 @@
(define-library (chibi channel)
(import (scheme) (srfi 9) (srfi 18))
(export Channel make-channel channel? channel-empty?
channel-send! channel-receive!)
(include "channel.scm"))