> > 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