diff options
author | Maxime Devos <maximedevos@telenet.be> | 2021-09-06 21:00:22 +0200 |
---|---|---|
committer | Maxime Devos <maximedevos@telenet.be> | 2021-09-21 12:20:58 +0200 |
commit | 75867c24192f49e76fbe31ce0dd8e774a2eac929 (patch) | |
tree | 6a5b4f3c5fd9ab59fcfe57cff4ca0e775679d47f /tests | |
parent | 9a809b8eb2cc9d3e6a47a0c8f463b078fcc8f30c (diff) | |
download | gnunet-scheme-75867c24192f49e76fbe31ce0dd8e774a2eac929.tar.gz gnunet-scheme-75867c24192f49e76fbe31ce0dd8e774a2eac929.zip |
mq-impl/stream: Close the port when stopping the fibers.
* gnu/gnunet/mq-impl/stream.scm
(prepare-port-message-queue)[closed-condition]: Document new uses.
(prepare-port-message-queue)[start-reader!]: Close port if
signal-condition! returns #false.
(prepare-port-message-queue)[start-writer!]: Likewise.
* tests/mq-stream.scm
(%false-if-broken-pipe): New procedure.
(false-if-broken-pipe): New macro.
("closed for writing --> handle-input! stops (port->message-queue)"):
Adjust test to resource leak fix.
(error-handler/regular): New procedure.
("port is closed at input eof")
("port is closed at output eof")
("port is closed at input/output eof"): New tests.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/mq-stream.scm | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/tests/mq-stream.scm b/tests/mq-stream.scm index d9cd667..e16aa1b 100644 --- a/tests/mq-stream.scm +++ b/tests/mq-stream.scm | |||
@@ -31,6 +31,7 @@ | |||
31 | ((rnrs io ports) #:select (open-bytevector-input-port)) | 31 | ((rnrs io ports) #:select (open-bytevector-input-port)) |
32 | ((rnrs base) #:select (assert)) | 32 | ((rnrs base) #:select (assert)) |
33 | (rnrs hashtables) | 33 | (rnrs hashtables) |
34 | ((rnrs exceptions) #:select (guard)) | ||
34 | (srfi srfi-26) | 35 | (srfi srfi-26) |
35 | (srfi srfi-43) | 36 | (srfi srfi-43) |
36 | (rnrs io ports) | 37 | (rnrs io ports) |
@@ -532,6 +533,20 @@ | |||
532 | ;; Should make 'yield-many' less fragile. | 533 | ;; Should make 'yield-many' less fragile. |
533 | #:parallelism 1)) | 534 | #:parallelism 1)) |
534 | 535 | ||
536 | (define (%false-if-broken-pipe thunk) | ||
537 | "Call @var{thunk} in an environment where EPIPE system errors are caught. | ||
538 | If an EPIPE system error is raised, return #f." | ||
539 | (guard (c ((and (eq? 'system-error (exception-kind c)) | ||
540 | (= EPIPE (car (list-ref (exception-args c) 3)))) | ||
541 | #f)) | ||
542 | (thunk))) | ||
543 | |||
544 | (define-syntax-rule (false-if-broken-pipe exp exp* ...) | ||
545 | ;; See %false-if-broken-pipe | ||
546 | (%false-if-broken-pipe | ||
547 | (lambda () | ||
548 | exp exp* ...))) | ||
549 | |||
535 | (test-assert "closed for writing --> handle-input! stops (port->message-queue)" | 550 | (test-assert "closed for writing --> handle-input! stops (port->message-queue)" |
536 | (call-with-spawner/wait | 551 | (call-with-spawner/wait |
537 | (lambda (spawn) | 552 | (lambda (spawn) |
@@ -569,8 +584,10 @@ | |||
569 | (pk 'waiting) | 584 | (pk 'waiting) |
570 | (wait end-of-file) | 585 | (wait end-of-file) |
571 | ;; Attempt to read a message (after buffering a message), even though | 586 | ;; Attempt to read a message (after buffering a message), even though |
572 | ;; the connection is half-closed. | 587 | ;; the connection is half-closed. Ignore broken pipe errors here: |
573 | (put-bytevector beta #vu8(0 4 0 0)) | 588 | ;; if a ‘broken pipe’ error happens here, that means ALPHA was closed, |
589 | ;; which is correct (tested in "port is closed at output"). | ||
590 | (false-if-broken-pipe (put-bytevector beta #vu8(0 4 0 0))) | ||
574 | ;; As the 'handle-input!' fiber should have exited already, 'receive!' | 591 | ;; As the 'handle-input!' fiber should have exited already, 'receive!' |
575 | ;; shouldn't be called. | 592 | ;; shouldn't be called. |
576 | (yield-many) | 593 | (yield-many) |
@@ -668,4 +685,48 @@ | |||
668 | (old-read-waiter p))))) | 685 | (old-read-waiter p))))) |
669 | (get-bytevector-some beta)))))) | 686 | (get-bytevector-some beta)))))) |
670 | 687 | ||
688 | (define (error-handler/regular . e) | ||
689 | (match e | ||
690 | ('(input:regular-end-of-file) (values)) | ||
691 | (_ (error "what ~a" e)))) | ||
692 | |||
693 | (test-assert "port is closed at input eof" | ||
694 | (call-with-spawner/wait | ||
695 | (lambda (spawn) | ||
696 | (define-values (alpha beta) (two-sockets)) | ||
697 | (define q (port->message-queue alpha no-handlers error-handler/regular | ||
698 | #:spawn spawn)) | ||
699 | (shutdown alpha 0) | ||
700 | (yield-many) | ||
701 | (sleep 0.05) ;; XXX yield-many above is unsufficient | ||
702 | (port-closed? alpha)) | ||
703 | #:parallelism 1)) ; to make the use of yield-many less fragile | ||
704 | |||
705 | (test-assert "port is closed at output eof" | ||
706 | (call-with-spawner/wait | ||
707 | (lambda (spawn) | ||
708 | (define-values (alpha beta) (two-sockets)) | ||
709 | (define mq (port->message-queue alpha no-handlers error-handler/regular | ||
710 | #:spawn spawn)) | ||
711 | (shutdown alpha 1) | ||
712 | ;; XXX It's not possible for the output eof to be waited for currently, | ||
713 | ;; so attempt to send a message to wake up the writing fiber. | ||
714 | (send-message! mq (bv-slice/read-write #vu8(0 4 0 0))) | ||
715 | (yield-many) | ||
716 | (sleep 0.05) ;; XXX yield-many above is unsufficient | ||
717 | (port-closed? alpha)) | ||
718 | #:parallelism 1)) ; to make the use of yield-many less fragile | ||
719 | |||
720 | (test-assert "port is closed at input/output eof" | ||
721 | (call-with-spawner/wait | ||
722 | (lambda (spawn) | ||
723 | (define-values (alpha beta) (two-sockets)) | ||
724 | (define q (port->message-queue alpha no-handlers error-handler/regular | ||
725 | #:spawn spawn)) | ||
726 | (shutdown alpha 2) | ||
727 | (yield-many) | ||
728 | (sleep 0.05) ;; XXX yield-many above is unsufficient | ||
729 | (port-closed? alpha)) | ||
730 | #:parallelism 1)) ; to make the use of yield-many less fragile | ||
731 | |||
671 | (test-end "mq-stream") | 732 | (test-end "mq-stream") |