I am wrapping an external C library, and it has a global initialize & shutdown function.
The documentation goes like this:
// The external library must be globally initialized before further use.
// It is intended to be called as part of the hosting process's startup
// sequence. Any failures that it can encounter are fatal and will abort
// the process.
// It is legal to call this multiple times, and each call must be balanced
// by a call to |externalLibraryGlobalShutdown|. The final shutdown call will
// permanently disable the compiler for the process and subsequent calls
// to initialize will fail/abort.
void externalLibraryGlobalInitialize();
// Destroys any process level resources the library may have created.
// This must be called prior to library unloading.
void externalLibraryGlobalShutdown();
How might I wrap this library safely into a crate, which can be imported multiple times through the dependency tree?
It supports one-time global initialization, but not global shutdown. I guess I need lifetimes or some kind of reference counting to keep track of, but I am not sure if it will work if imported multiple times through the dependency tree...
Importing is a purely compile-time concept. It doesn't affect runtime at all. But you shouldn't be doing global shutdown anyway, that usually only leads to surprising bugs. Declare a static and leave the library initialized once called by anyone from anywhere.
It's the same deal with lifetime parameters. They are purely compile-time concepts that don't influence when something is dropped at all. Dynamic liveness of values can be dependent on runtime conditions and is unaffected by lifetimes. Lifetimes only affect whether some particular code compiles, which includes checking drop order and validity scopes, but it doesn't change them.