12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- (define-condition-type &port-invalid &assertion make-port-invalid
- port-invalid?
- (expression port-invalid-expression)
- (return port-invalid-return))
- ;; (:documentation "Signals an error if the returned port is invalid.")
- (define-report ((condition &port-invalid) stream)
- (format stream "Port returned by the expression ~s (~s) is not valid."
- (port-invalid-expression condition)
- (port-invalid-return condition)))
- (define (%get-nil-task task)
- "Returns (task-self) if 'task' is nil, 'task' otherwise."
- (if (null? task)
- #'(task-self)
- task))
- (define (with-port-generic destroy port-name creation task body)
- "Generates code for port using and releasing."
- #`(let ((#,port-name #,creation))
- (cond
- ((port-valid-p #,port-name)
- (with-cleanup #,(destroy port-name (%get-nil-task task))
- #,@body))
- (#t (raise (make-port-invalid '#,creation #,port-name))))))
- (define-syntax with-port-deallocate
- (lambda (s)
- "Uses a port and then port-deallocate's"
- (syntax-case s ()
- ((_ port-name creation #:body body task)
- (with-port-generic (lambda (port task)
- #`(port-deallocate! #,port #,task))
- #'port-name #'creation #'task #'body))
- ((_ port-name creation #:body body)
- #'(with-port-deallocate port-name creation #nil #:body body)))))
- (define-syntax with-port-destroy
- (lambda (s)
- "Uses a port and then port-destroy's"
- (syntax-case s ()
- ((_ port-name creation task #:body body)
- (with-port-generic (lambda (port task)
- #`(port-destroy #,port #,task))
- #'port-name #'creation #'task #'body))
- ((_ port-name creation #:body body)
- #'(with-port-destroy port-name creation body #nil)))))
- (define (%generate-release-list port task ls)
- "Generate code for port and port rights releasing based on the 'ls'
- list syntax."
- (define (generate-release right)
- (syntax-case right ()
- ((#:deallocate) #`(port-deallocate! #,port #,task))
- (_ #`(port-mod-refs #,port #,right -1 #,task))))
- (syntax-map generate-release (syntax-cadr ls)))
- (define* (with-port port-name creation #:optional (task #nil)
- (release-list #nil) #:key body)
- "Generic with-port, uses a port initialized with 'creation'
- and then releases rights.
- release-list can have #:deallocate or any port right specified to port-mod-rights."
- (with-port-generic (lambda (port task)
- #`(progn #,@(%generate-release-list port task release-list)))
- port-name creation task body))
|