Discussion:
[gambit-list] detecting closed ports
Dimitris Vyzovitis
2018-03-24 08:29:05 UTC
Permalink
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...

-- vyzo
Adam
2018-03-24 09:43:01 UTC
Permalink
The BSD/unix API does not allow this for TCP sockets, as in tapping into
the OS' knowledge of whether a connection was closed, the only way to learn
that is by trying to write to it.

However with respect to Gambit knowing whether |close-port| was applied on
a port, of course you should be able to retrieve that.
Post by Dimitris Vyzovitis
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Dimitris Vyzovitis
2018-03-24 09:51:52 UTC
Permalink
You can't tell if a file descriptor is closed in general, that's not what I
am after.
I just want to know if close-port was applied to the port.

-- vyzo
Post by Adam
The BSD/unix API does not allow this for TCP sockets, as in tapping into
the OS' knowledge of whether a connection was closed, the only way to learn
that is by trying to write to it.
However with respect to Gambit knowing whether |close-port| was applied on
a port, of course you should be able to retrieve that.
Post by Dimitris Vyzovitis
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Marc Feeley
2018-03-24 11:56:09 UTC
Permalink
Knowing that close-port was called on a port is not sufficient to tell if the port is “closed” or not. Apart from what it means for a port to be “closed”, there are ports that don’t close permanently when close-port is called on them. See the example below of a pipe used for the communication between two threads. It allows using close-port to send an “end-of-file” to the other thread multiple times.

For “device” ports however, there is a state in the port object at the C level. The fields read_stage and write_stage will be different from ___STAGE_OPEN when the device port no longer accepts reading or writing. Perhaps that is the information you want. Note that not all ports are device ports.

Marc


(define in #f)
(define out #f)

(receive (i o) (open-string-pipe (list permanent-close: #f))
(set! in i)
(set! out o))

(define (send x)
(write x out)
(newline out)
(force-output out)
(thread-sleep! 0.5))

(define (close)
(close-output-port out)
(thread-sleep! 0.5))

(thread-start!
(make-thread
(lambda ()
(let loop ()
(let ((x (read in)))
(pp x)
(loop))))))

(send '(11))
(send '(22))

(close)

(send '(33))
(send '(44))

(close)
(close)

(send '(55))

;; output:
;; (11)
;; (22)
;; #!eof
;; (33)
;; (44)
;; #!eof
;; #!eof
;; (55)
You can't tell if a file descriptor is closed in general, that's not what I am after.
I just want to know if close-port was applied to the port.
-- vyzo
The BSD/unix API does not allow this for TCP sockets, as in tapping into the OS' knowledge of whether a connection was closed, the only way to learn that is by trying to write to it.
However with respect to Gambit knowing whether |close-port| was applied on a port, of course you should be able to retrieve that.
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs coverage...
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Dimitris Vyzovitis
2018-03-24 11:59:51 UTC
Permalink
that's a very good point, i keep forgetting about the non-permanent closure
of pipes and its usability.
snarfing the read/write stage from the device may be ok, although we won't
be able to tell for pure scheme ports.

-- vyzo
Post by Marc Feeley
Knowing that close-port was called on a port is not sufficient to tell if
the port is “closed” or not. Apart from what it means for a port to be
“closed”, there are ports that don’t close permanently when close-port is
called on them. See the example below of a pipe used for the communication
between two threads. It allows using close-port to send an “end-of-file”
to the other thread multiple times.
For “device” ports however, there is a state in the port object at the C
level. The fields read_stage and write_stage will be different from
___STAGE_OPEN when the device port no longer accepts reading or writing.
Perhaps that is the information you want. Note that not all ports are
device ports.
Marc
(define in #f)
(define out #f)
(receive (i o) (open-string-pipe (list permanent-close: #f))
(set! in i)
(set! out o))
(define (send x)
(write x out)
(newline out)
(force-output out)
(thread-sleep! 0.5))
(define (close)
(close-output-port out)
(thread-sleep! 0.5))
(thread-start!
(make-thread
(lambda ()
(let loop ()
(let ((x (read in)))
(pp x)
(loop))))))
(send '(11))
(send '(22))
(close)
(send '(33))
(send '(44))
(close)
(close)
(send '(55))
;; (11)
;; (22)
;; #!eof
;; (33)
;; (44)
;; #!eof
;; #!eof
;; (55)
Post by Dimitris Vyzovitis
You can't tell if a file descriptor is closed in general, that's not
what I am after.
Post by Dimitris Vyzovitis
I just want to know if close-port was applied to the port.
-- vyzo
The BSD/unix API does not allow this for TCP sockets, as in tapping into
the OS' knowledge of whether a connection was closed, the only way to learn
that is by trying to write to it.
Post by Dimitris Vyzovitis
However with respect to Gambit knowing whether |close-port| was applied
on a port, of course you should be able to retrieve that.
Post by Dimitris Vyzovitis
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...
Post by Dimitris Vyzovitis
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Dimitris Vyzovitis
2018-03-24 12:25:17 UTC
Permalink
What about using the port roptions/woptions in conjunction with the
permanent-close property?
This could work for u8vector/string/vector ports, but I don't know about
pipes.

-- vyzo
Post by Dimitris Vyzovitis
that's a very good point, i keep forgetting about the non-permanent
closure of pipes and its usability.
snarfing the read/write stage from the device may be ok, although we won't
be able to tell for pure scheme ports.
-- vyzo
Post by Marc Feeley
Knowing that close-port was called on a port is not sufficient to tell if
the port is “closed” or not. Apart from what it means for a port to be
“closed”, there are ports that don’t close permanently when close-port is
called on them. See the example below of a pipe used for the communication
between two threads. It allows using close-port to send an “end-of-file”
to the other thread multiple times.
For “device” ports however, there is a state in the port object at the C
level. The fields read_stage and write_stage will be different from
___STAGE_OPEN when the device port no longer accepts reading or writing.
Perhaps that is the information you want. Note that not all ports are
device ports.
Marc
(define in #f)
(define out #f)
(receive (i o) (open-string-pipe (list permanent-close: #f))
(set! in i)
(set! out o))
(define (send x)
(write x out)
(newline out)
(force-output out)
(thread-sleep! 0.5))
(define (close)
(close-output-port out)
(thread-sleep! 0.5))
(thread-start!
(make-thread
(lambda ()
(let loop ()
(let ((x (read in)))
(pp x)
(loop))))))
(send '(11))
(send '(22))
(close)
(send '(33))
(send '(44))
(close)
(close)
(send '(55))
;; (11)
;; (22)
;; #!eof
;; (33)
;; (44)
;; #!eof
;; #!eof
;; (55)
Post by Dimitris Vyzovitis
You can't tell if a file descriptor is closed in general, that's not
what I am after.
Post by Dimitris Vyzovitis
I just want to know if close-port was applied to the port.
-- vyzo
The BSD/unix API does not allow this for TCP sockets, as in tapping
into the OS' knowledge of whether a connection was closed, the only way to
learn that is by trying to write to it.
Post by Dimitris Vyzovitis
However with respect to Gambit knowing whether |close-port| was applied
on a port, of course you should be able to retrieve that.
Post by Dimitris Vyzovitis
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...
Post by Dimitris Vyzovitis
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Dimitris Vyzovitis
2018-03-24 15:13:18 UTC
Permalink
I settled for the following implementation, which is spec compliant:
https://github.com/vyzo/gerbil/blob/master/src/lang/scheme/base-ports.ss#L88

It first checks the roptions/woptions with macro-closed?, and then if it is
a device port it checks the read/write_stage.
It doesn't understand permanent-close, but the spec only requires that
close-* has been called on the port and has no notion of either threads or
non-permenantly closed ports.

-- vyzo
Post by Dimitris Vyzovitis
What about using the port roptions/woptions in conjunction with the
permanent-close property?
This could work for u8vector/string/vector ports, but I don't know about
pipes.
-- vyzo
Post by Dimitris Vyzovitis
that's a very good point, i keep forgetting about the non-permanent
closure of pipes and its usability.
snarfing the read/write stage from the device may be ok, although we
won't be able to tell for pure scheme ports.
-- vyzo
Post by Marc Feeley
Knowing that close-port was called on a port is not sufficient to tell
if the port is “closed” or not. Apart from what it means for a port to be
“closed”, there are ports that don’t close permanently when close-port is
called on them. See the example below of a pipe used for the communication
between two threads. It allows using close-port to send an “end-of-file”
to the other thread multiple times.
For “device” ports however, there is a state in the port object at the C
level. The fields read_stage and write_stage will be different from
___STAGE_OPEN when the device port no longer accepts reading or writing.
Perhaps that is the information you want. Note that not all ports are
device ports.
Marc
(define in #f)
(define out #f)
(receive (i o) (open-string-pipe (list permanent-close: #f))
(set! in i)
(set! out o))
(define (send x)
(write x out)
(newline out)
(force-output out)
(thread-sleep! 0.5))
(define (close)
(close-output-port out)
(thread-sleep! 0.5))
(thread-start!
(make-thread
(lambda ()
(let loop ()
(let ((x (read in)))
(pp x)
(loop))))))
(send '(11))
(send '(22))
(close)
(send '(33))
(send '(44))
(close)
(close)
(send '(55))
;; (11)
;; (22)
;; #!eof
;; (33)
;; (44)
;; #!eof
;; #!eof
;; (55)
Post by Dimitris Vyzovitis
You can't tell if a file descriptor is closed in general, that's not
what I am after.
Post by Dimitris Vyzovitis
I just want to know if close-port was applied to the port.
-- vyzo
The BSD/unix API does not allow this for TCP sockets, as in tapping
into the OS' knowledge of whether a connection was closed, the only way to
learn that is by trying to write to it.
Post by Dimitris Vyzovitis
However with respect to Gambit knowing whether |close-port| was
applied on a port, of course you should be able to retrieve that.
Post by Dimitris Vyzovitis
Is there a reasonable way to detect whether a port has been closed?
I want to implement input-port-open? and output-port-open? for r7rs
coverage...
Post by Dimitris Vyzovitis
-- vyzo
_______________________________________________
Gambit-list mailing list
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Loading...