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
signature.asc
Description: This is a digitally signed message part
_______________________________________________ IOLib-devel mailing list [email protected] http://common-lisp.net/cgi-bin/mailman/listinfo/iolib-devel
