# Initialization & Finalization

This chapter details the function used to initialize
the library before first use, and the function used to
finalize the library and deallocate any resources used by the library.

## Initialization

```c
typedef struct {
    int16_t num_task_threads;
    int16_t max_task_threads;
    int16_t num_expire_threads;
    int16_t max_expire_threads;
    int16_t num_poller_threads;
    int16_t max_poller_threads;
    int16_t num_resolver_threads;
} nng_init_params;

extern nng_err nng_init(nng_init_params *params);
```

Before using other interfaces in this library, it is necessary to initialize
the library. The {{i:`nng_init`}} function performs this initialization.

The function is idempotent, although on tear down, every call to `nng_init` must
be paired with a call to [`nng_fini`] or no resources will be released.
This allows for libraries consuming these interfaces to safely initialize and finalize
the library without disrupting other consumers in the same process.

Further, only the first call to this function may have a value of _params_ other than `NULL`.
If _params_ is not `NULL`, and the library has already been intiazed, then `nng_init` will
return [`NNG_EBUSY`].

In some cases it is desirable to tune certain runtime parameters for the library, which
can be done by supplying a non-`NULL` _params_ argument.

### Parameters

The individual fields of the `nng_init_params` structure can be used to adjust certain
runtime tunables for the library. There is no guarantee that these tunables are implemented,
and applications should not depend upon them for correct operation.

Any member of `nng_init_params` that is set to zero will be ignored, and any built in default
will be used instead for that value.

> [!NOTE]
> Applications should make sure that structure is zero initialized before calling `nng_init`.

The following parameters are present:

- `num_task_threads` and `max_task_threads` \
  Configures the number of threads to use for tasks, which are used principally for completion
  callbacks. The maximum value can be used to provide an upper limit while still allowing
  for a dynamically calculated value to be used, as long as it does not exceed the maximum.

- `num_expire_threads` and `max_expire_threads` \
  Configures the number of threads used for expiring operations. Using a larger value will
  reduce contention on some common locks, and may improve performance.

- `num_poller_threads` and `max_poller_threads` \
  Configures the number of threads to be used for performing I/O. Not all configurations support
  changing these values.

- `num_resolver_threads` \
  Changes the number of threads used for asynchronous DNS look ups.

## Finalization

```c
extern void nng_fini(void);
```

When the consumer is ready to deallocate any resources allocated by the library, it should call
the {{i:`nng_fini`}} function. Each call to `nng_fini` should be paired with an earlier call to
[`nng_init`].

After calling `nng_fini`, the consuming application must not make any other calls to NNG functions,
except that it may use `nng_init` to initialize the application for further use.

{{#include ../xref.md}}
