> > Aren't global pools still cleaned up on exit? If the threads are still
> > running we'll still have the same problem. The only way I see to fix this
> > is to make sure that all threads have terminated before cleaning up
> > the pool.
> 
> I don't see that they're getting cleaned up on exit.

Pools that are created with a NULL parent are actually created as
child-pools of the global_pool. The global_pool is destroyed in
apr_pool_terminate(), which is called from apr_terminate(), which
is registered with atexit().

> As far as making sure all threads have terminated before cleaning up
> the pool:  How do we do that in a graceless shutdown?  If we hang
> around much longer, the parent is going to kill us and we won't be
> able to run cleanups anyway.

I don't see any good way out of this situation, here are two bad ways
I see out:

1) check for workers_may_exit upon returning from any EINTR-returning syscall
   Con: yuck, the number of places where we would have to do this is
        way too large.

2) introduce apr_thread_cancel()
   Con: a) many thread libraries leak kernel resources when threads are
           cancelled.
        b) We'd also have to introduce apr_thread_setcancelstate, et al.
           *and* we would have to be sure to clean up thing like the
           accept mutex (it would be bad to be canceled while holding
           the accept mutex).

A couple questions:
  - What happens when we call shutdown() on the listen socket? Are
    accepted sockets allowed to remain (I'm assuming so).

  - Could the listener thread keep a list of accepted socket descriptors
    and then close them all when we receive the signal to gracelessly
    stop the server? We could optionally _not_ handle the resulting
    socket errors (Afterall, that might be good information to have --
    the admin just intentionally killed off a bunch of connections.)

-aaron

Reply via email to