Commit | Line | Data |
---|---|---|
e1e02a22 | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
e1e02a22 | 3 | * |
0235b0db | 4 | * Copyright (C) 2010-2019 EfficiOS Inc. and Linux Foundation |
e1e02a22 PP |
5 | */ |
6 | ||
0235b0db MJ |
7 | #ifndef BABELTRACE2_CTF_WRITER_OBJECT_H |
8 | #define BABELTRACE2_CTF_WRITER_OBJECT_H | |
9 | ||
e1e02a22 PP |
10 | #ifdef __cplusplus |
11 | extern "C" { | |
12 | #endif | |
13 | ||
14 | /** | |
15 | @defgroup refs Reference counting management | |
16 | @ingroup apiref | |
17 | @brief Common reference counting management for all Babeltrace objects. | |
18 | ||
19 | @code | |
217cf9d3 | 20 | #include <babeltrace2-ctf-writer/object.h> |
e1e02a22 PP |
21 | @endcode |
22 | ||
23 | The macros and functions of this module are everything that is needed | |
24 | to handle the <strong><em>reference counting</em></strong> of | |
25 | Babeltrace objects. | |
26 | ||
27 | Any Babeltrace object can be shared by multiple owners thanks to | |
28 | <a href="https://en.wikipedia.org/wiki/Reference_counting">reference | |
29 | counting</a>. | |
30 | ||
31 | The Babeltrace C API complies with the following key principles: | |
32 | ||
33 | 1. When you call an API function which accepts a Babeltrace object | |
34 | pointer as a parameter, the API function <strong>borrows the | |
35 | reference</strong> for the <strong>duration of the function</strong>. | |
36 | ||
37 | @image html ref-count-user-calls.png | |
38 | ||
39 | The API function can also get a new reference if the system needs a | |
40 | more persistent reference, but the ownership is <strong>never | |
41 | transferred</strong> from the caller to the API function. | |
42 | ||
43 | In other words, the caller still owns the object after calling any | |
44 | API function: no function "steals" the user's reference (except | |
45 | bt_ctf_object_put_ref()). | |
46 | ||
47 | 2. An API function which \em returns a Babeltrace object pointer to the | |
48 | user returns a <strong>new reference</strong>. The caller becomes an | |
49 | owner of the object. | |
50 | ||
51 | @image html ref-count-api-returns.png | |
52 | ||
53 | It is your responsibility to discard the object when you don't | |
54 | need it anymore with bt_ctf_object_put_ref(). | |
55 | ||
56 | For example, see bt_ctf_value_array_get(). | |
57 | ||
58 | 3. A Babeltrace object pointer received as a parameter in a user | |
59 | function called back from an API function is a | |
60 | <strong>borrowed</strong>, or <strong>weak reference</strong>: if you | |
61 | need a reference which is more persistent than the duration of the | |
62 | user function, call bt_ctf_object_get_ref() on the pointer. | |
63 | ||
64 | @image html ref-count-callback.png | |
65 | ||
66 | For example, see bt_ctf_value_map_foreach_entry(). | |
67 | ||
68 | The two macros BT_CTF_OBJECT_PUT_REF_AND_RESET() and BT_CTF_OBJECT_MOVE_REF() operate on \em variables rather | |
69 | than pointer values. You should use BT_CTF_OBJECT_PUT_REF_AND_RESET() instead of bt_ctf_object_put_ref() when | |
70 | possible to avoid "double puts". For the same reason, you should use use | |
71 | BT_CTF_OBJECT_MOVE_REF() instead of performing manual reference moves between | |
72 | variables. | |
73 | ||
74 | @file | |
75 | @brief Reference counting management macros and functions. | |
76 | @sa refs | |
77 | ||
78 | @addtogroup refs | |
79 | @{ | |
80 | */ | |
81 | ||
82 | /** | |
83 | @brief Calls bt_ctf_object_put_ref() on a variable named \p _var, then | |
84 | sets \p _var to \c NULL. | |
85 | ||
86 | Using this macro is considered safer than calling bt_ctf_object_put_ref() because it | |
87 | makes sure that the variable which used to contain a reference to a | |
88 | Babeltrace object is set to \c NULL so that a future BT_CTF_OBJECT_PUT_REF_AND_RESET() or | |
89 | bt_ctf_object_put_ref() call will not cause another, unwanted reference decrementation. | |
90 | ||
91 | @param[in,out] _var Name of a variable containing a | |
92 | Babeltrace object's address (this address | |
93 | can be \c NULL). | |
94 | ||
95 | @post <strong>If \p _var does not contain \p NULL</strong>, | |
96 | its reference count is decremented. | |
97 | @post \p _var contains \c NULL. | |
98 | ||
99 | @sa BT_CTF_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a | |
100 | variable to another. | |
101 | */ | |
102 | #define BT_CTF_OBJECT_PUT_REF_AND_RESET(_var) \ | |
103 | do { \ | |
104 | bt_ctf_object_put_ref(_var); \ | |
105 | (_var) = NULL; \ | |
106 | } while (0) | |
107 | ||
108 | /** | |
109 | @brief Transfers the ownership of a Babeltrace object from a variable | |
110 | named \p _var_src to a variable named \p _var_dst. | |
111 | ||
112 | This macro implements the following common pattern: | |
113 | ||
114 | 1. Call bt_ctf_object_put_ref() on \p _var_dst to make sure the previous reference | |
115 | held by \p _var_dst is discarded. | |
116 | 2. Assign \p _var_src to \p _var_dst. | |
117 | 3. Set \p _var_src to \c NULL to avoid future, unwanted reference | |
118 | decrementation of \p _var_src. | |
119 | ||
120 | @warning | |
121 | You must \em not use this macro when both \p _var_dst and | |
122 | \p _var_src contain the same Babeltrace object address and the reference | |
123 | count of this object is 1. The initial call to bt_ctf_object_put_ref() on \p _var_dst | |
124 | would destroy the object and leave a dangling pointer in \p _var_dst. | |
125 | ||
126 | @param[in,out] _var_dst Name of the destination variable, containing | |
127 | either the address of a Babeltrace object to | |
128 | put first, or \c NULL. | |
129 | @param[in,out] _var_src Name of the source variable, containing | |
130 | either the address of a Babeltrace object to | |
131 | move, or \c NULL. | |
132 | ||
133 | @pre <strong>If \p _var_dst and \p _var_src contain the same | |
134 | value which is not \c NULL</strong>, this object's reference | |
135 | count is greater than 1. | |
136 | @post <strong>If \c _var_dst is not \c NULL</strong>, its reference | |
137 | count is decremented. | |
138 | @post \p _var_dst is equal to the value of \p _var_src \em before | |
139 | you called this macro. | |
140 | @post \p _var_src is \c NULL. | |
141 | ||
142 | @sa BT_CTF_OBJECT_PUT_REF_AND_RESET(): Calls bt_ctf_object_put_ref() on a variable, then sets it to \c NULL. | |
143 | */ | |
144 | #define BT_CTF_OBJECT_MOVE_REF(_var_dst, _var_src) \ | |
145 | do { \ | |
146 | bt_ctf_object_put_ref(_var_dst); \ | |
147 | (_var_dst) = (_var_src); \ | |
148 | (_var_src) = NULL; \ | |
149 | } while (0) | |
150 | ||
151 | /** | |
152 | @brief Increments the reference count of the Babeltrace object \p obj. | |
153 | ||
154 | @param[in] obj Babeltrace object of which to get a new reference | |
155 | (can be \c NULL). | |
156 | @returns \p obj | |
157 | ||
158 | @post <strong>If \c obj is not \c NULL</strong>, its reference | |
159 | count is incremented. | |
160 | ||
161 | @sa bt_ctf_object_put_ref(): Decrements the reference count of a Babeltrace object. | |
162 | */ | |
163 | void *bt_ctf_object_get_ref(void *obj); | |
164 | ||
165 | /** | |
166 | @brief Decrements the reference count of the Babeltrace object | |
167 | \p obj. | |
168 | ||
169 | When the object's reference count reaches 0, the object can no longer | |
170 | be accessed and is considered \em destroyed. | |
171 | ||
172 | @remarks | |
173 | You should use the BT_CTF_OBJECT_PUT_REF_AND_RESET() macro instead of calling bt_ctf_object_put_ref() since the | |
174 | former is generally safer. | |
175 | ||
176 | @param[in] obj Babeltrace object of which to drop a reference | |
177 | (can be \c NULL). | |
178 | ||
179 | @post <strong>If \c obj is not \c NULL</strong>, its reference | |
180 | count is decremented. | |
181 | ||
182 | @sa BT_CTF_OBJECT_PUT_REF_AND_RESET(): Calls bt_ctf_object_put_ref() on a variable, then sets it to \c NULL. | |
183 | @sa BT_CTF_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a | |
184 | variable to another. | |
185 | @sa bt_ctf_object_get_ref(): Increments the reference count of a Babeltrace object. | |
186 | */ | |
187 | void bt_ctf_object_put_ref(void *obj); | |
188 | ||
189 | /** | |
190 | @} | |
191 | */ | |
192 | ||
193 | #ifdef __cplusplus | |
194 | } | |
195 | #endif | |
196 | ||
924dc299 | 197 | #endif /* BABELTRACE2_CTF_WRITER_OBJECT_H */ |