Registry Library#
The resource registry utility is defined in resource_registry.h
. A registry is a layer over a UTHash table for resource servers to track their resources. It includes some utility functions for adding / finding / removing entries from the registry, plus managing reference counts.
Registry Entries#
Resource servers should ‘subclass’ the generic resource registry entry type to create their own registry entry type.
A registry entry can be any structure, as long as it includes the resource_registry_node_t
as the first parameter.
typedef struct _my_resource_registry_node {
resource_registry_node_t gen;
// <... server-specific data here ...>
} my_resource_registry_node_t;
Registry Keys#
The registry key is a 64-bit value that uniquely identifies a resource within a registry. Usually, a registry is specific to a resource space, so a resource’s object ID can be the same as its registry key.
Resource servers can insert resource registry entries with preset object IDs using resource_registry_insert
(for example, we use the inode number as the file resource ID).
Alternatively, you can use resource_registry_insert_new_id
to insert a resource node and assign it the next available ID. There may be an upper limit on object IDs (see badge scalability), so the max_object_id
option (set in resource_registry_initialize
) should be set to the maximum object ID. If nodes are deleted from the registry, their IDs will eventually be reassigned to a new node. If there are no IDs available, the operation will fail.
Reference Counts#
The resource_registry_inc
and resource_registry_dec
functions manage a registry entry’s reference count. The count is initialized to 1 after a registry insert, and when it reaches zero, the registry entry is deleted (but entries can also be deleted forcefully with resource_registry_delete
).
If the on_delete
option is set in resource_registry_initialize
, then the registry will call the on_delete
function when an entry is about to be deleted from the registry. This way, a resource server can perform any necessary cleanup before the registry entry is freed.
UTHash#
Since the registry uses UTHash under the hood, we occasionally use the UTHash macros.
Deletion-safe iteration over all entries of a registry:
resource_registry_t registry = <...>;
resource_registry_node_t *curr, *tmp;
HASH_ITER(hh, registry.head, curr, tmp)
{
my_resource_registry_node_t *node = (my_resource_registry_node_t *)curr;
// ...
}