Hi, I am wondering if any devs here would be willing to help me figure out how to properly close an O_NONBLOCK socket. I had a browse of libcurl, but couldn't find exactly what was done. Forgive me, I'm not actually using libcurl (I use curl though!), I have actually written a webserver which isn't functioning correctly.
The problem appears to be a design fault in Posix which implies an efficient and safe webserver actually cannot be written :) What happens: after writing the last data, shutdown() and/or close() is called, which immediately flushes away all the stuff just written to the socket buffers. This is either "allowed" or "required" by Posix, depending on which bit you read. Linux appears to do this. My workaround for the moment is to put a delay before the shutdown/close, but that fails the "efficient" requirement because it unnecessarily leaves a socket handing around for which the data may have been sent. [On my slicehost account I had to set the delay to about 20 seconds] SO_LINGER was somehow meant to solve this problem, but it only works on blocking sockets. On OSX there is a hacky but acceptable solution using SO_NWRITE but that isn't standard and not implemented on Linux. It allows discovering how much unwritten data there is in the buffer and therefore in conjunction with a polling loop allows closing on a timeout or when all the data is written or error occurs, whichever comes first. Switching to a blocking socket may work. According to OpenGroup, closing a blocking socket should actually return immediately but still try to write the buffers out, unless SO_LINGER is active in which case it blocks. Unfortunately, the specification is ambiguous *and* contradictory. Says this: If fildes refers to a socket, close() shall cause the socket to be destroyed. If the socket is in connection-mode, and the SO_LINGER option is set for the socket with non-zero linger time, and the socket has untransmitted data, then close() shall block for up to the current linger interval until all data is transmitted. That doesn't actually happen on Linux (when the socket is O_NONBLOCK) AFICT anyhow :) I've been pulling my hair out on this for 3 years or so.. How does curl close sending sockets? [I know curl uses non-blocking I/O] -- john skaller [email protected] ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
