X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=include%2Fbabeltrace%2Fref.h;h=fe266ec3e2653afc0038c47921c7884da02781ab;hb=8654d3067604d63b6df17571cac79c4485d6496f;hp=f03f8c9b01f67c9494c8bbf6476a2a84f2e1159f;hpb=b82cd9f0ac23ce23386d4cf3d6b46aaf09293770;p=babeltrace.git diff --git a/include/babeltrace/ref.h b/include/babeltrace/ref.h index f03f8c9b..fe266ec3 100644 --- a/include/babeltrace/ref.h +++ b/include/babeltrace/ref.h @@ -27,69 +27,191 @@ * SOFTWARE. */ -/* - * BT_PUT: calls bt_put() with a variable, then sets this variable to NULL. - * - * A common action with Babeltrace objects is to create or get one, perform - * an action with it, and then put it. To avoid putting it a second time - * later (if an error occurs, for example), the variable is often reset - * to NULL after putting the object it points to. Since this is so - * common, the BT_PUT() macro can be used to do just that. - * - * It is safe to call this function with a NULL object. - * - * @param obj Babeltrace object. - */ -#define BT_PUT(_obj) \ +#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_put()). + +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_put(). + + For example, see bt_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_get() on the pointer. + + @image html ref-count-callback.png + + For example, see bt_value_map_foreach(). + +The two macros BT_PUT() and BT_MOVE() operate on \em variables rather +than pointer values. You should use BT_PUT() instead of bt_put() when +possible to avoid "double puts". For the same reason, you should use use +BT_MOVE() instead of performing manual reference moves between +variables. + +@file +@brief Reference counting management macros and functions. +@sa refs + +@addtogroup refs +@{ +*/ + +/** +@brief Calls bt_put() on a variable named \p _var, then + sets \p _var to \c NULL. + +Using this macro is considered safer than calling bt_put() 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_PUT() or +bt_put() 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_MOVE(): Transfers the ownership of a Babeltrace object from a + variable to another. +*/ +#define BT_PUT(_var) \ do { \ - bt_put(_obj); \ - (_obj) = NULL; \ + bt_put(_var); \ + (_var) = NULL; \ } while (0) -/* - * BT_MOVE: transfers the ownership of an object, setting the old owner to NULL. - * - * This macro sets the variable _dst to the value of the variable _src, - * then sets _src to NULL, effectively moving the ownership of an - * object from one variable to the other. - * - * @param obj Babeltrace object. - */ -#define BT_MOVE(_dst, _src) \ - do { \ - (_dst) = (_src);\ - (_src) = NULL; \ +/** +@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_put() 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_put() 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_PUT(): Calls bt_put() on a variable, then sets it to \c NULL. +*/ +#define BT_MOVE(_var_dst, _var_src) \ + do { \ + bt_put(_var_dst); \ + (_var_dst) = (_var_src); \ + (_var_src) = NULL; \ } while (0) -/* - * bt_get: increments the reference count of a Babeltrace object. - * - * The same number of bt_get() and bt_put() (plus one extra bt_put() to release - * the initial reference acquired at creation) have to be performed to destroy a - * Babeltrace object. - * - * It is safe to call this function with a NULL object. - * - * @param obj Babeltrace object. - * - * Returns obj. - */ +/** +@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_put(): Decrements the reference count of a Babeltrace object. +*/ void *bt_get(void *obj); -/* - * bt_put: decrements the reference count of a Babeltrace object. - * - * The same number of bt_get() and bt_put() (plus one extra bt_put() to release - * bt_put() to release the initial reference done at creation) have to be - * performed to destroy a Babeltrace object. - * - * The object is feed when its reference count is decremented to 0 by a call to - * bt_put(). - * - * It is safe to call this function with a NULL object. - * - * @param obj Babeltrace object. - */ +/** +@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_PUT() macro instead of calling bt_put() 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_PUT(): Calls bt_put() on a variable, then sets it to \c NULL. +@sa BT_MOVE(): Transfers the ownership of a Babeltrace object from a + variable to another. +@sa bt_get(): Increments the reference count of a Babeltrace object. +*/ void bt_put(void *obj); +/** +@} +*/ + +#ifdef __cplusplus +} +#endif + #endif /* BABELTRACE_REF_H */