On 25.07.2018 17:46, William A Rowe Jr wrote: > Giving this problem some thought... > > If an aprfoo-1.so provider is linked to the libfoo.so library, and we > track the init state and perform it only once, it seems that apr > should never try to de-init or unload the .so provider for the > lifespan of the process. > > This should help us avoid some redundant initialization. While we > could free resources atexit()
Shared libraries (remember, APR is usually a shared lib too) should avoid using the atexit() mechanism. It's a good way to shoot yourself in the foot; on Unix, you *may*, depending on the platform, have the atexit() handlers run in a predictable order. But on Windows, each DLL has its own atexit() queue and all predictability goes out the window. > , any spin of trying to repeatedly unload and reload any .so provider > seems to be inherently messy and unstable. We see this issue with > mod_ssl, etc, where the statics may be freed and reinitialized, and > causes the resource leakage mentioned by Yann. Yes, unloading a DSO that wasn't designed for it is always messy, and probably always wrong, too. > Once loaded and initialized, we recieve no benefit from repeatedly > altering the processes' library mmaps, and doing so after we spin up > contending threads is an even worse scenario. Leaving them loaded > should not have an adverse effect, and if it becomes swapped out due > to lack of use during the lifespan of the process, should not be > particularly harmful. > > While httpd modules are often unloaded and reloaded, the underlying > libfoo.so is still stuck in process to libapr-1.so, so those should > remain stable. > > Does this make sense? Yes, however: apr_dso_load() takes a pool as context, and when the pool is destroyed, all the related DSO modules are unloaded, whether you want them to be or not. Even using a global pool for apr_dso_load() does not help because you still will have no control of the lifetime of other pools or code that may still be live and depend on the DSO module when it's unloaded at global pool cleanup time. We've had constant and painful problems with this in Subversion, having to track down random crashes at process exit. We've implemented really horrible workarounds, and I'm still not sure we've covered every edge case. APR should either stop using pools in the apr_dso_* implementation -- it's better to malloc() the apr_dso_handle_t and risk its leaking than to randomly break code -- or it should provide a type of pool that is never cleaned up for this purpose. But I think the former is better. -- Brane