From: Amos Jeffries Date: Tue, 12 Jan 2010 06:44:41 +0000 (+1300) Subject: Full re-working of the way AcceptFD are handled in Squid X-Git-Tag: SQUID_3_2_0_1~468 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=382c67a914a2e960eac7dc45ab4b2f0fe76ea81e;p=thirdparty%2Fsquid.git Full re-working of the way AcceptFD are handled in Squid Previously: a pre-defined fdc_table was initialized and left waiting just in case any of the available FD were needed as a listening port. At which point a handler was assigned and select was setup. Much action was wasted initializing the array on startup and shutdown, and various unnecessary maintenance references in comms every FD closure. Now: one merely opens a socket, defines the AsyncCall handler for the listening FD and creates a ListenStateData object from the two. When a listener socket is done with, delete the ListenStateData and the FD gets closed. Callers are responsible for maintaining a pointer to the ListenStateData. ListenStateData silently does all the comm processing for setting up and watching for new connections. Including whether accept() on a port is delayed until more FD are available. Then when any accept() is completed it sends the resulting FD and ConnectionDetails objects to the assigned callback. COMM_ERR_CLOSING and re-scheduling themselves is now not generally relevant to layers higher than comm on listening sockets. The callbacks never get called at all unless a real new connection has been accepted. The old code is still used internally by the comm layer, but details of error handling and re-scheduling of accept() never leak out into higher level code now. ListenStateData can be created in use-once or accept-many form. * use-once are intended for short temporary listening sockets such as FTP passive data links. A single inbound connection is allowed after which the handler self-destructs. * accept-many are for long term FD such as the http_port listeners which continuously accept new connections and pass them all to the same handler until something causes the ListenStateData to die (deletion, or self destruct under fatal socket IO errors). The previous existing AcceptLimiter is slightly remodeled to work with ListenStateData* instead of an intermediary callback reference type. And also altered from LIFO to FIFO behavior for better client response times under load. All the code relevant to comm layer processing of accept() is bundled into libcomm-listener.la. TODO: * wrap the SSL handshake into ListenStateData. That way SSL on some sockets can be treated as a real transport layer and for example httpsAccept and httpAccept merged into one function. * there is one bug uncovered, that when the accept() handler is deleted and the port closed while it has been deferred. The deferred queue needs to be cleared of all (multiple) deferral events, or they will be scheduled uselessly and may segfault with FD errors. This only gets hit if Squid is shutdown during active load limiting. --- 382c67a914a2e960eac7dc45ab4b2f0fe76ea81e