cs: send immutable byte strings to custom output ports
Related to #2726
This commit is contained in:
parent
61b365f4be
commit
2988917f03
|
@ -560,6 +560,35 @@
|
|||
(test 3 sync (write-bytes-avail-evt #"Bye" cap-port))
|
||||
(test "HELLOBYE" get-output-string orig-port)
|
||||
|
||||
;; Make sure output ports get immutable byte strings
|
||||
(let ()
|
||||
(define i? #f)
|
||||
(define p (make-output-port
|
||||
'test
|
||||
always-evt
|
||||
(lambda (bstr start end buffer? enable-break?)
|
||||
(set! i? (immutable? bstr))
|
||||
(- end start))
|
||||
void
|
||||
(lambda (v buffer? enable-break?)
|
||||
1)
|
||||
(lambda (bstr start end)
|
||||
(set! i? (immutable? bstr))
|
||||
(wrap-evt always-evt (lambda (v) (- end start))))
|
||||
(lambda (v)
|
||||
(wrap-evt always-evt (lambda (v) 1)))))
|
||||
(test 5 write-bytes (bytes-copy #"hello") p)
|
||||
(test #t values i?)
|
||||
(set! i? #f)
|
||||
(test 5 write-bytes #"hello" p)
|
||||
(test #t values i?)
|
||||
(set! i? #f)
|
||||
(test #t evt? (write-bytes-avail-evt #"hello" p))
|
||||
(test #t values i?)
|
||||
(set! i? #f)
|
||||
(test #t evt? (write-bytes-avail-evt (bytes-copy #"hello") p))
|
||||
(test #t values i?))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Peeking in a limited pipe extends the limit:
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#lang racket/base
|
||||
(require "../common/check.rkt"
|
||||
(require (only-in racket/unsafe/ops unsafe-bytes->immutable-bytes!)
|
||||
"../common/check.rkt"
|
||||
"../common/class.rkt"
|
||||
"../host/thread.rkt"
|
||||
"port.rkt"
|
||||
|
@ -116,30 +117,40 @@
|
|||
[else
|
||||
(send core-output-port output-pipe write-out bstr start end non-block/buffer? enable-break? copy?)])]
|
||||
[else
|
||||
(define-values (imm-bstr imm-start imm-end)
|
||||
;; If `copy?` is false, we're allowed to do anything with the string,
|
||||
;; so it's ok to destroy it and get an immutable string. If `copy?`
|
||||
;; is true, then we allocate a fresh string, anyway:
|
||||
(let ([immutable! unsafe-bytes->immutable-bytes!])
|
||||
(if (and copy? (not (immutable? bstr)))
|
||||
(values (immutable! (subbytes bstr start end)) 0 (- end start))
|
||||
(values (immutable! bstr) start end))))
|
||||
(define r
|
||||
;; Always tell user port to re-enable breaks if it blocks, since
|
||||
;; we always disable breaks:
|
||||
(let ([enable-break? (and (not non-block/buffer?) (break-enabled))])
|
||||
(parameterize-break #f
|
||||
(non-atomically
|
||||
(if copy?
|
||||
(user-write-out (subbytes bstr start end) 0 (- end start) non-block/buffer? enable-break?)
|
||||
(user-write-out bstr start end non-block/buffer? enable-break?))))))
|
||||
(check-write-result '|user port write| r start end non-block/buffer?)
|
||||
(user-write-out imm-bstr imm-start imm-end non-block/buffer? enable-break?)))))
|
||||
(check-write-result '|user port write| r imm-start imm-end non-block/buffer?)
|
||||
(cond
|
||||
[(pipe-output-port? r)
|
||||
(write-out self bstr start end non-block/buffer? enable-break? copy?)]
|
||||
(write-out self imm-bstr imm-start imm-end non-block/buffer? enable-break? copy?)]
|
||||
[(evt? r)
|
||||
(wrap-check-write-evt-result '|user port write| r start end non-block/buffer?)]
|
||||
(wrap-check-write-evt-result '|user port write| r imm-start imm-end non-block/buffer?)]
|
||||
[else r])]))
|
||||
|
||||
(define (get-write-evt self bstr start end)
|
||||
(define-values (imm-bstr imm-start imm-end)
|
||||
(if (immutable? bstr)
|
||||
(values bstr start end)
|
||||
(values (unsafe-bytes->immutable-bytes! (subbytes bstr start end)) 0 (- end start))))
|
||||
(end-atomic)
|
||||
(define r (user-get-write-evt bstr start end))
|
||||
(define r (user-get-write-evt imm-bstr imm-start imm-end))
|
||||
(unless (evt? r)
|
||||
(raise-result-error '|user port get-write-evt| "evt?" r))
|
||||
(start-atomic)
|
||||
(wrap-check-write-evt-result '|user port write-evt| r start end #t))
|
||||
(wrap-check-write-evt-result '|user port write-evt| r imm-start imm-end #t))
|
||||
|
||||
(define (write-out-special self v non-block/buffer? enable-break?)
|
||||
(let ([enable-break? (and (not non-block/buffer?) (break-enabled))])
|
||||
|
|
Loading…
Reference in New Issue
Block a user