## Managed modules

`p11-kit` wraps PKCS#11 modules to manage them and customize their functionality so that they are able to be shared between multiple callers in the same process.

Each caller that uses the `p11_kit_modules_load()` or `p11_kit_module_load()` function gets independent wrapped PKCS#11 module(s). This is unless a caller or module configuration specifies that a module should be used in an unmanaged fashion.

When modules are managed, the following aspects are wrapped and coordinated:

- Calls to `C_Initialize` and `C_Finalize` can be called by multiple callers.

  The first time that the managed module `C_Initialize` is called, the PKCS#11 module's actual `C_Initialize` function is called. Subsequent calls by other callers will cause `p11-kit` to increment an internal initialization count, rather than calling `C_Initialize` again.

  Multiple callers can call the managed `C_Initialize` function concurrently from different threads and `p11-kit` will guarantee that this managed in a thread-safe manner.

- When the managed module `C_Finalize` is used to finalize a module, each time it is called it decrements the internal initialization count for that module. When the internal initialization count reaches zero, the module's actual `C_Finalize` function is called.

  Multiple callers can call the managed `C_Finalize` function concurrently from different threads and `p11-kit` will guarantee that this managed in a thread-safe manner.

- Call to `C_CloseAllSessions` only close the sessions that the caller of the managed module has opened. This allows the `C_CloseAllSessions` function to be used without closing sessions for other callers of the same PKCS#11 module.

- Managed modules have ability to log PKCS#11 method calls for debugging purposes. See the `log-calls = yes` module configuration option.

- Managed modules have the ability to be remoted to another machine or isolated in their own process. See the `remote = ...` module configuration option.