Margo instance lifetime
In the previous sections, we have used margo_init
(or one of its variant)
to initialize a Margo instance, and margo_finalize
to destroy it. When
doing so, we have to understand that the actual destruction of the Margo instance
may not happen in margo_finalize
itself: if margo_finalize
is
called from an RPC, or if another ULT is blocked on margo_wait_for_finalize
,
then the Margo instance will be destroyed respectively after the RPC, and in
margo_wait_for_finalize
.
This lifetime management may not be suitable when wrapping Margo code in a
higher-level language that uses destructors or garbage collection. Even in C, it may
be useful to ensure that the Margo instance remains valid after its finalization,
for instance to be able to cleanup Argobots or Mercury objects (e.g. ABT_mutex
or
hg_addr_t
) after the Mercury progress loop has been stopped.
To help with such lifetime management, Margo instances have an internal reference count. This reference count is initialize at 1 when the instance is created. It is decreased by 1 when the instance is finalized, and the instance is destroyed when the reference count goes to 0.
This reference count can be increased and decreased by the user by calling
margo_instance_ref_incr
and margo_instance_release
, respectively.
If the program calls margo_finalize
on an instance with a reference count
greater than 1, the progress loop will be stopped, making the instance unable
to send and receive RPCs, but the instance itself won’t be destroyed until
margo_instance_release
has been called as many times as needed to make
the reference count go to 0.