Object lifecycle management: HarfBuzz Manual

## Object lifecycle management

Each object type in HarfBuzz provides a `create()` method. Some object types provide additional variants of `create()` to handle special cases or to speed up common tasks; those variants are documented in the API reference. For example, `hb_blob_create_from_file()` constructs a new blob directly from the contents of a file.

All objects are created with an initial reference count of `1`. Client programs can increase the reference count on an object by calling its `reference()` method. Whenever a client program is finished with an object, it should call its corresponding `destroy()` method. The destroy method will decrease the reference count on the object and, whenever the reference count reaches zero, it will also destroy the object and free all of the associated memory.

All of HarfBuzz's object-lifecycle-management APIs are thread-safe (unless you compiled HarfBuzz from source with the `HB_NO_MT` configuration flag), even when the object as a whole is not thread-safe. It is also permissible to `reference()` or to `destroy()` the `NULL` value.

Some objects are thread-safe after they have been constructed and set up. The general pattern is to `create()` the object, make a few `set_*()` calls to set up the object, and then use it without further modification.

To ensure that such an object is not modified, client programs can explicitly mark an object as immutable. HarfBuzz provides `make_immutable()` methods to mark an object as immutable and `is_immutable()` methods to test whether or not an object is immutable. Attempts to use setter functions on immutable objects will fail silently; see the API Reference manual for specifics.

Note also that there are no "make mutable" methods. If client programs need to alter an object previously marked as immutable, they will need to make a duplicate of the original.

Finally, object constructors (and, indeed, as much of the shaping API as possible) will never return `NULL`. Instead, if there is an allocation error, each constructor will return an “empty” object singleton.

These empty-object singletons are inert and safe (although typically useless) to pass around. This design choice avoids having to check for `NULL` pointers all throughout the code.

In addition, this “empty” object singleton can also be accessed using the `get_empty()` method of the object type in question.