Atexit and Plugins

I’m reviewing some legacy code using OpenSSL since it needs to be updated to become compatible for universal binary builds. The old implementation called now deprecated openssl cleanup functions. In the current openssl documentation I find the following information on the current OPENSSL_cleanup

The OPENSSL_cleanup() function deinitialises OpenSSL (both libcrypto and libssl). All
resources allocated by OpenSSL are freed. Typically there should be no need to call this
function directly as it is initiated automatically on application exit. This is done via
the standard C library atexit() function. In the event that the application will close in
a manner that will not call the registered atexit() handlers then the application should
call OPENSSL_cleanup() directly. Developers of libraries using OpenSSL are discouraged
from calling this function and should instead, typically, rely on auto-deinitialisation.
This is to avoid error conditions where both an application and a library it depends on
both use OpenSSL, and the library deinitialises it before the application has finished
using it.

Now I wonder what’s the correct way of performing such cleanup work in a plugin context? I guess assigning something to atexit from within a plugin will make it be called when the host will be shut down, not when the last instance of the plugin is removed from the project. Am I right? And if so, what is the correct hook for such functions in the context of a plugin? And what if a function pointer, assigned to atexit pointed to a function in the plugin loaded, that might already be unloaded from the process at the time when the host is shut down.

I can see e.g. DeletedAtShutdown::deleteAll being called inside shutdownJuce_GUI which seems to be called from the various plugin wrapper cleanup handlers, so setting up a singleton inheriting DeletedAtShutdown could be a solution, but still I wonder if there are any side effects to expect if the library implementation assigns a cleanup handler via atexit?

I just did some testing and added a something like

atexit([] { std::cout << "atexit called"; });

to a plugin processor constructor, loaded the plugin, closed the session and quit the host. At least for Reaper and Logic this causes no trouble, the call gets invoked as expected on plugin close, the plugin and with it the test lambda seems to be still loaded in the process even after closing the session containing it.

Can this be expected in any case?