fix dequeue! to actually not hold onto queue elements

(the comments on line 11-13 said that it did this already,
but it didn't)

also add a test case to be sure that it stays this way
This commit is contained in:
Robby Findler 2012-11-21 06:29:45 -06:00
parent f3a95ba9c7
commit ac7c37812b
2 changed files with 20 additions and 3 deletions

View File

@ -30,8 +30,13 @@
(define (dequeue! q)
(unless (queue? q) (raise-type-error dequeue! "queue" 0 q))
(let ([old (queue-head q)])
(unless old (error 'dequeue! "empty queue"))
(set-queue-head! q (link-tail old))
(unless old (raise-type-error 'dequeue! "non-empty queue" 0 q))
(cond
[(eq? old (queue-tail q))
(set-queue-tail! q #f)
(set-queue-head! q #f)]
[else
(set-queue-head! q (link-tail old))])
(link-value old)))
(define (queue->list queue)

View File

@ -63,7 +63,19 @@
(enqueue! q 2)
(check-equal? (dequeue! q) 1)
(check-equal? (dequeue! q) 2)
(check-exn exn:fail? (lambda () (dequeue! q))))))
(check-exn exn:fail? (lambda () (dequeue! q)))))
(test-case "don't leak last element"
(let* ([thing (box 'box-that-queue-should-not-hold-onto)]
[wb (make-weak-box thing)]
[q (make-queue)])
(enqueue! q thing)
(set! thing #f)
(dequeue! q)
(collect-garbage)
(check-false (weak-box-value wb))
;; need a reference to 'q' after looking in the
;; box or else the whole queue gets collected
(check-true (queue? q)))))
(test-suite "queue misc"
(test-case "queue as a sequence"
(let ([queue (make-queue)])