[iolib-devel] with-open-socket oddness
Stelian Ionescu
sionescu at cddr.org
Wed Feb 10 20:17:06 UTC 2010
On Mon, 2010-02-08 at 22:31 -0600, Peter Keller wrote:
> Hello,
>
> I discovered in my boundary testing of with-open-socket that it sort of has
> a funny behavior I didn't expect.
>
> Basically, I had a top level code like this in a blocking i/o tcp ipv4
> client talking to a server:
>
> (with-open-socket
> (socket :stuff :things)
>
> ;; set up i/o handlers, each wrap their reads and writes around
> ;; handler-case. A disconnector on the sockets removes the io handlers, but
> ;; doesn't close the socket since with-open-socket should do it.
>
> (handler-case
> ;; run forever until empty (meaning we disconnected from the server),
> ;; then return.
> (event-dispatch *base*)
>
> (hangup ()
> (format t "Hangup while writing to server~%"))
>
> (end-of-file ()
> (format t "End of file from server~%"))))
>
> Now, what happened was, under certain conditions where there is inflight
> data on the sockets, a registered handler could get a signaled condition,
> specifically hangup, that tells me the server went away on a write. This
> is expected. I disconnect the socket which removes the i/o handlers, which
> causes event-dispatch to return since there are no registered handlers....
> and then bam! The with-open-stream performs a (finish-output) and (close) on
> the socket and I get _another_ hangup condition!
>
> So I had to rewrite the code like this moving the handler-case up one scope:
>
> (handler-case
> (with-open-socket
> (socket :things :stuff)
> ;; set up i/o handlers, each wrap their reads and writes around
> ;; handler-case. A disconnector on the sockets removes the io handlers, but
> ;; doesn't close the socket since with-open-socket should do it.
> (event-dispatch *base*))
>
> (hangup ()
> (format t "Hangup while writing to server~%"))
>
> (end-of-file ()
> (format t "End of file from server~%"))))
>
> Is this a to be expected scenario in condition handling with respect to
> with-open-socket? Is this idiomatic code?
This is to be expected. This is what happens: one of the handlers
signals a HANGUP(which is Posix EPIPE), the handler-case handles it and
returns. At his point, since the code wrapped by with-open-socket
returns, w-o-s closes the socket with :abort NIL, which tries again to
flush the output buffer(:abort T would just close the file descriptor),
which causes another HANGUP to be signaled.
> Should the disconnector function close the socket even though with-open-socket
> also closes it? I'm not sure of the right thing to do here.
My opinion is that it's not a good idea to mix with-open-socket and the
event loop because w-o-s is thought for a synchronous data flow. The
only exception to that is if you use w-o-s to open the server socket.
With active sockets, it's better to close them from within the event
loop.
--
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.
http://common-lisp.net/project/iolib
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <https://mailman.common-lisp.net/pipermail/iolib-devel/attachments/20100210/b3367084/attachment.sig>
More information about the iolib-devel
mailing list