Block on remove if Q is empty

This commit is contained in:
Justin Ethier 2019-06-26 18:45:04 -04:00
parent 0b4803a7ef
commit 2e60569dd0

View file

@ -29,7 +29,6 @@
queue-add! queue-add!
%queue-add! ;; DEBUG %queue-add! ;; DEBUG
queue-remove! queue-remove!
%queue-remove! ;; DEBUG
queue-clear! queue-clear!
queue-size queue-size
queue-capacity queue-capacity
@ -50,13 +49,13 @@
;if start == end after an add, then vector is full, need to resize ;if start == end after an add, then vector is full, need to resize
(define-record-type <queue> (define-record-type <queue>
(%make-queue store start end lock) (%make-queue store start end lock cv)
queue? queue?
(store q:store q:set-store!) (store q:store q:set-store!)
(start q:start q:set-start!) (start q:start q:set-start!)
(end q:end q:set-end!) (end q:end q:set-end!)
(lock q:lock q:set-lock!) (lock q:lock q:set-lock!)
;(empty-lock q:empty-lock q:set-empty-lock!) (cv q:cv q:set-cv!)
) )
(define (make-queue) (define (make-queue)
@ -66,7 +65,7 @@
0 0
0 0
(make-mutex) (make-mutex)
;(make-mutex) (make-condition-variable)
))) )))
(define (queue . elems) (define (queue . elems)
@ -94,6 +93,7 @@
(mutex-lock! (q:lock q)) (mutex-lock! (q:lock q))
(%queue-add! q obj) (%queue-add! q obj)
(mutex-unlock! (q:lock q)) (mutex-unlock! (q:lock q))
(condition-variable-signal! (q:cv q))
) )
(define (%queue-resize! q) (define (%queue-resize! q)
@ -115,23 +115,19 @@
) )
(define (queue-remove! q) (define (queue-remove! q)
(let ((result #f)) (let loop ()
(mutex-lock! (q:lock q)) (mutex-lock! (q:lock q))
(set! result (%queue-remove! q))
(mutex-unlock! (q:lock q))
result))
;- queue-remove! - remove item (when to block? would be nice if we can block until an item becomes available) (cond
; maybe block by default, but have an optional timeout ((= (q:start q) (q:end q))
(define (%queue-remove! q) ;; Wait for CV, indicating data is ready
(cond (mutex-unlock! (q:lock q) (q:cv q))
((= (q:start q) (q:end q)) (loop))
(write "queue is already empty")) (else
(else (let ((result (vector-ref (q:store q) (q:start q))))
(let ((result (vector-ref (q:store q) (q:start q)))) (q:set-start! q (inc (q:start q) (vector-length (q:store q))))
(q:set-start! q (inc (q:start q) (vector-length (q:store q)))) (mutex-unlock! (q:lock q))
result))) result)))))
)
(define (queue-clear! q) (define (queue-clear! q)
(mutex-lock! (q:lock q)) (mutex-lock! (q:lock q))