On Tue, 2008-04-08 at 22:23 +0200, Henrik Nordstrom wrote:
> I still think the cbdata model is generally preferrable. Much less to
> keep track of. For pconn it would need one cbdata object per idle fd,
> and having only that object invalidated when the fd is taken out of
> the pconn queue for whatever reason.
I am not sure I understand. Who will invalidate the cbdata protecting
that fd? The idle pconn pool object? So, essentially, you are proposing
to create little objects that would be responsible for keeping
fd-related state and deleting/invalidating them when fd goes away,
right? If yes, then this is fine with me.
You will need to pass the pointer to that keeper object to comm though,
which will complicate the implementation a little because standard comm
calls do not know about that pointer. You will need to add a custom call
class. There are a few examples of such custom calls (CommCalls being a
complex one).
The alternative is to make each little keeper object an AsyncJob child
so that it can schedule/receive calls without any custom call code. It
can also quit at any time (AsyncJobs are cbdata-protected). We normally
have "transaction" jobs handling a busy file descriptor. Here, we will
have an "idle transaction" job. This alternative is cleaner/simpler, but
might be too performance-heavy for the idle connection pool.
FWIW, my previous call cancellation comments referred to your general
problem:
'A' executes. Deregisters interest in 'B' and assumes it won't
get called, but it's already in the async call queue.
The general solution to that would be to cancel all pending calls
associated with the fd when the idle pconn pool decides it no longer
needs that fd. The second general solution (discussed above) is to turn
the idle fd keeper into a job that can "quit".
HTH,
Alex.
P.S. Since cbdata does not work well with inheritance, we should be
extra careful when adding new cbdata dependencies and should replace
cbdata with a C++ friendly class in v3.2.