/* * SPDX-License-Identifier: MIT * * Copyright (C) 2010-2019 EfficiOS Inc. and Linux Foundation */ #ifndef BABELTRACE2_CTF_WRITER_OBJECT_H #define BABELTRACE2_CTF_WRITER_OBJECT_H #ifdef __cplusplus extern "C" { #endif /** @defgroup refs Reference counting management @ingroup apiref @brief Common reference counting management for all Babeltrace objects. @code #include @endcode The macros and functions of this module are everything that is needed to handle the reference counting of Babeltrace objects. Any Babeltrace object can be shared by multiple owners thanks to reference counting. The Babeltrace C API complies with the following key principles: 1. When you call an API function which accepts a Babeltrace object pointer as a parameter, the API function borrows the reference for the duration of the function. @image html ref-count-user-calls.png The API function can also get a new reference if the system needs a more persistent reference, but the ownership is never transferred from the caller to the API function. In other words, the caller still owns the object after calling any API function: no function "steals" the user's reference (except bt_ctf_object_put_ref()). 2. An API function which \em returns a Babeltrace object pointer to the user returns a new reference. The caller becomes an owner of the object. @image html ref-count-api-returns.png It is your responsibility to discard the object when you don't need it anymore with bt_ctf_object_put_ref(). For example, see bt_ctf_value_array_get(). 3. A Babeltrace object pointer received as a parameter in a user function called back from an API function is a borrowed, or weak reference: if you need a reference which is more persistent than the duration of the user function, call bt_ctf_object_get_ref() on the pointer. @image html ref-count-callback.png For example, see bt_ctf_value_map_foreach_entry(). The two macros BT_CTF_OBJECT_PUT_REF_AND_RESET() and BT_CTF_OBJECT_MOVE_REF() operate on \em variables rather than pointer values. You should use BT_CTF_OBJECT_PUT_REF_AND_RESET() instead of bt_ctf_object_put_ref() when possible to avoid "double puts". For the same reason, you should use use BT_CTF_OBJECT_MOVE_REF() instead of performing manual reference moves between variables. @file @brief Reference counting management macros and functions. @sa refs @addtogroup refs @{ */ /** @brief Calls bt_ctf_object_put_ref() on a variable named \p _var, then sets \p _var to \c NULL. Using this macro is considered safer than calling bt_ctf_object_put_ref() because it makes sure that the variable which used to contain a reference to a Babeltrace object is set to \c NULL so that a future BT_CTF_OBJECT_PUT_REF_AND_RESET() or bt_ctf_object_put_ref() call will not cause another, unwanted reference decrementation. @param[in,out] _var Name of a variable containing a Babeltrace object's address (this address can be \c NULL). @post If \p _var does not contain \p NULL, its reference count is decremented. @post \p _var contains \c NULL. @sa BT_CTF_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a variable to another. */ #define BT_CTF_OBJECT_PUT_REF_AND_RESET(_var) \ do { \ bt_ctf_object_put_ref(_var); \ (_var) = NULL; \ } while (0) /** @brief Transfers the ownership of a Babeltrace object from a variable named \p _var_src to a variable named \p _var_dst. This macro implements the following common pattern: 1. Call bt_ctf_object_put_ref() on \p _var_dst to make sure the previous reference held by \p _var_dst is discarded. 2. Assign \p _var_src to \p _var_dst. 3. Set \p _var_src to \c NULL to avoid future, unwanted reference decrementation of \p _var_src. @warning You must \em not use this macro when both \p _var_dst and \p _var_src contain the same Babeltrace object address and the reference count of this object is 1. The initial call to bt_ctf_object_put_ref() on \p _var_dst would destroy the object and leave a dangling pointer in \p _var_dst. @param[in,out] _var_dst Name of the destination variable, containing either the address of a Babeltrace object to put first, or \c NULL. @param[in,out] _var_src Name of the source variable, containing either the address of a Babeltrace object to move, or \c NULL. @pre If \p _var_dst and \p _var_src contain the same value which is not \c NULL, this object's reference count is greater than 1. @post If \c _var_dst is not \c NULL, its reference count is decremented. @post \p _var_dst is equal to the value of \p _var_src \em before you called this macro. @post \p _var_src is \c NULL. @sa BT_CTF_OBJECT_PUT_REF_AND_RESET(): Calls bt_ctf_object_put_ref() on a variable, then sets it to \c NULL. */ #define BT_CTF_OBJECT_MOVE_REF(_var_dst, _var_src) \ do { \ bt_ctf_object_put_ref(_var_dst); \ (_var_dst) = (_var_src); \ (_var_src) = NULL; \ } while (0) /** @brief Increments the reference count of the Babeltrace object \p obj. @param[in] obj Babeltrace object of which to get a new reference (can be \c NULL). @returns \p obj @post If \c obj is not \c NULL, its reference count is incremented. @sa bt_ctf_object_put_ref(): Decrements the reference count of a Babeltrace object. */ void *bt_ctf_object_get_ref(void *obj); /** @brief Decrements the reference count of the Babeltrace object \p obj. When the object's reference count reaches 0, the object can no longer be accessed and is considered \em destroyed. @remarks You should use the BT_CTF_OBJECT_PUT_REF_AND_RESET() macro instead of calling bt_ctf_object_put_ref() since the former is generally safer. @param[in] obj Babeltrace object of which to drop a reference (can be \c NULL). @post If \c obj is not \c NULL, its reference count is decremented. @sa BT_CTF_OBJECT_PUT_REF_AND_RESET(): Calls bt_ctf_object_put_ref() on a variable, then sets it to \c NULL. @sa BT_CTF_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a variable to another. @sa bt_ctf_object_get_ref(): Increments the reference count of a Babeltrace object. */ void bt_ctf_object_put_ref(void *obj); /** @} */ #ifdef __cplusplus } #endif #endif /* BABELTRACE2_CTF_WRITER_OBJECT_H */