Async-call work replaces event-based asynchronous calls with
stand-alone implementation. The common async call API allows Squid
core do call, debug, and troubleshoot all callback handlers in a
uniform way.
An async "job" API is introduced to manage independent logical threads
or work such as protocol transaction handlers on client, server, and
ICAP sides. These jobs should communicate with each other using async
calls to minimize dependencies and avoid reentrant callback loops.
These changes will eventually improve overall code quality, debugging
quality, and Squid robustness.
Below you will find log messages from the async-call branch that are
relevant to the file(s) being committed.
Added initial implelentation of AsyncCall-based wrappers for
comm callbacks. The comm layer no longer calls callbacks from
the select loop. Instead, the select loop schedules async
calls. Scheduled calls are then called from the main loop (like
all other async calls), after the select loop completes.
Removed accept loop. We cannot loop because async calls do not
get fired during the loop and, hence, cannot register new
callbacks for new ready FDs.
The loop is implicit now. When the next callback is registered,
we check whether the last accept(2) call was successful or
OPTIMISTIC_IO is defined and call acceptNext() again if yes.
AcceptNext() may schedule another async call (using the
being-submitted callback) if the socket was still ready. Since
callbacks are fired until there are no callabacks left, we
still have an accept loop.
Removed CommDispatcher as unused.
Removed unused IOFCB, IOWCB, and CWCB.
Removed class fdc_t. After CommCallbackData removal, fdc_t was
only used to check that a FD is "active" and to check that a FD
is half_closed. fd_table flags.open seems to be identical to
the "active" state flag so we use that now, via newly added
isOpen() static function. AbortChecker already maintains
half_closed status.
The accept-specific functionality is still implemented by
AcceptFD class. Removed fdc_t used to marshall accept-ralted
calls to AcceptFD anyway. fdc_table now stores AcceptFDs
directly. I did not rename the table to ease merging with other
code, but added a TODO for that.
Removed calls to comm_iocallbackpending(). They were added to
"Speed up processing of queued events significantly, to not
cause large delays when under low load" but I do not see how
having pending callbacks can be relevant because all pending
callbacks are (should be) executed before FDs are probed.
Removed unused nullCallback() methods.
Removed CommCallbackData and related code. It looks like it
remained after one of the big comm rewrites, just to handle
accept errors. We can now schedule an async call to notify of
those errors and do not seem to need CommCallbackData at all.
Removed commfd_completed_events: a list of completed (but not
yet fired) callbacks. We simply schedule the async call now
instead of maintaining our own list of callbacks to call. This
change allows us to eliminate the CommDispatcher class (which
was the motivation behind these changes), but I have not done
that yet.
For comm_io_callback_t, being active seems to be the same as
having a callback. Replaced active data member with a method
that checks for the callback presence.
Relaxed comm_read_cancel() preconditions so that the callers do
not have to check all the assertions inside before calling that
function.
The CommCall code is still more complex than I want it to be.
However, these are low-level interfaces that most developers
will not have to deal with and the complexity will be
significantly reduced if we get rid of old style
function-pointer based callbacks, which is probably desirable
for several reasons.