Commit | Line | Data |
---|---|---|
65300d60 PP |
1 | #ifndef BABELTRACE_OBJECT_H |
2 | #define BABELTRACE_OBJECT_H | |
de3dd40e PP |
3 | |
4 | /* | |
de3dd40e PP |
5 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation |
6 | * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com> | |
83509119 | 7 | * Copyright (c) 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
de3dd40e PP |
8 | * |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 | * of this software and associated documentation files (the "Software"), to deal | |
11 | * in the Software without restriction, including without limitation the rights | |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 | * copies of the Software, and to permit persons to whom the Software is | |
14 | * furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
18 | * | |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
25 | * SOFTWARE. | |
26 | */ | |
27 | ||
26162993 PP |
28 | #ifdef __cplusplus |
29 | extern "C" { | |
30 | #endif | |
31 | ||
b62d3f21 PP |
32 | /** |
33 | @defgroup refs Reference counting management | |
34 | @ingroup apiref | |
35 | @brief Common reference counting management for all Babeltrace objects. | |
36 | ||
9197569d | 37 | @code |
65300d60 | 38 | #include <babeltrace/object.h> |
9197569d PP |
39 | @endcode |
40 | ||
b62d3f21 PP |
41 | The macros and functions of this module are everything that is needed |
42 | to handle the <strong><em>reference counting</em></strong> of | |
43 | Babeltrace objects. | |
44 | ||
223f6c6a | 45 | Any Babeltrace object can be shared by multiple owners thanks to |
b62d3f21 | 46 | <a href="https://en.wikipedia.org/wiki/Reference_counting">reference |
223f6c6a | 47 | counting</a>. |
b62d3f21 | 48 | |
223f6c6a PP |
49 | The Babeltrace C API complies with the following key principles: |
50 | ||
51 | 1. When you call an API function which accepts a Babeltrace object | |
52 | pointer as a parameter, the API function <strong>borrows the | |
53 | reference</strong> for the <strong>duration of the function</strong>. | |
54 | ||
55 | @image html ref-count-user-calls.png | |
56 | ||
57 | The API function can also get a new reference if the system needs a | |
58 | more persistent reference, but the ownership is <strong>never | |
59 | transferred</strong> from the caller to the API function. | |
60 | ||
61 | In other words, the caller still owns the object after calling any | |
62 | API function: no function "steals" the user's reference (except | |
65300d60 | 63 | bt_object_put_ref()). |
223f6c6a PP |
64 | |
65 | 2. An API function which \em returns a Babeltrace object pointer to the | |
66 | user returns a <strong>new reference</strong>. The caller becomes an | |
67 | owner of the object. | |
68 | ||
69 | @image html ref-count-api-returns.png | |
70 | ||
71 | It is your responsibility to discard the object when you don't | |
65300d60 | 72 | need it anymore with bt_object_put_ref(). |
223f6c6a PP |
73 | |
74 | For example, see bt_value_array_get(). | |
75 | ||
76 | 3. A Babeltrace object pointer received as a parameter in a user | |
77 | function called back from an API function is a | |
78 | <strong>borrowed</strong>, or <strong>weak reference</strong>: if you | |
09ac5ce7 | 79 | need a reference which is more persistent than the duration of the |
65300d60 | 80 | user function, call bt_object_get_ref() on the pointer. |
223f6c6a PP |
81 | |
82 | @image html ref-count-callback.png | |
83 | ||
07208d85 | 84 | For example, see bt_value_map_foreach_entry(). |
b62d3f21 | 85 | |
65300d60 PP |
86 | The two macros BT_OBJECT_PUT_REF_AND_RESET() and BT_OBJECT_MOVE_REF() operate on \em variables rather |
87 | than pointer values. You should use BT_OBJECT_PUT_REF_AND_RESET() instead of bt_object_put_ref() when | |
b62d3f21 | 88 | possible to avoid "double puts". For the same reason, you should use use |
65300d60 | 89 | BT_OBJECT_MOVE_REF() instead of performing manual reference moves between |
b62d3f21 PP |
90 | variables. |
91 | ||
92 | @file | |
93 | @brief Reference counting management macros and functions. | |
94 | @sa refs | |
95 | ||
96 | @addtogroup refs | |
97 | @{ | |
98 | */ | |
99 | ||
100 | /** | |
65300d60 | 101 | @brief Calls bt_object_put_ref() on a variable named \p _var, then |
34d0da31 | 102 | sets \p _var to \c NULL. |
b62d3f21 | 103 | |
65300d60 | 104 | Using this macro is considered safer than calling bt_object_put_ref() because it |
b62d3f21 | 105 | makes sure that the variable which used to contain a reference to a |
65300d60 PP |
106 | Babeltrace object is set to \c NULL so that a future BT_OBJECT_PUT_REF_AND_RESET() or |
107 | bt_object_put_ref() call will not cause another, unwanted reference decrementation. | |
b62d3f21 | 108 | |
34d0da31 PP |
109 | @param[in,out] _var Name of a variable containing a |
110 | Babeltrace object's address (this address | |
111 | can be \c NULL). | |
b62d3f21 | 112 | |
34d0da31 PP |
113 | @post <strong>If \p _var does not contain \p NULL</strong>, |
114 | its reference count is decremented. | |
115 | @post \p _var contains \c NULL. | |
b62d3f21 | 116 | |
65300d60 | 117 | @sa BT_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a |
b62d3f21 PP |
118 | variable to another. |
119 | */ | |
65300d60 PP |
120 | #define BT_OBJECT_PUT_REF_AND_RESET(_var) \ |
121 | do { \ | |
122 | bt_object_put_ref(_var); \ | |
123 | (_var) = NULL; \ | |
de3dd40e PP |
124 | } while (0) |
125 | ||
b62d3f21 | 126 | /** |
34d0da31 PP |
127 | @brief Transfers the ownership of a Babeltrace object from a variable |
128 | named \p _var_src to a variable named \p _var_dst. | |
b62d3f21 PP |
129 | |
130 | This macro implements the following common pattern: | |
131 | ||
65300d60 | 132 | 1. Call bt_object_put_ref() on \p _var_dst to make sure the previous reference |
b62d3f21 PP |
133 | held by \p _var_dst is discarded. |
134 | 2. Assign \p _var_src to \p _var_dst. | |
135 | 3. Set \p _var_src to \c NULL to avoid future, unwanted reference | |
136 | decrementation of \p _var_src. | |
137 | ||
138 | @warning | |
139 | You must \em not use this macro when both \p _var_dst and | |
140 | \p _var_src contain the same Babeltrace object address and the reference | |
65300d60 | 141 | count of this object is 1. The initial call to bt_object_put_ref() on \p _var_dst |
b62d3f21 PP |
142 | would destroy the object and leave a dangling pointer in \p _var_dst. |
143 | ||
34d0da31 PP |
144 | @param[in,out] _var_dst Name of the destination variable, containing |
145 | either the address of a Babeltrace object to | |
146 | put first, or \c NULL. | |
147 | @param[in,out] _var_src Name of the source variable, containing | |
148 | either the address of a Babeltrace object to | |
149 | move, or \c NULL. | |
b62d3f21 PP |
150 | |
151 | @pre <strong>If \p _var_dst and \p _var_src contain the same | |
34d0da31 PP |
152 | value which is not \c NULL</strong>, this object's reference |
153 | count is greater than 1. | |
b62d3f21 PP |
154 | @post <strong>If \c _var_dst is not \c NULL</strong>, its reference |
155 | count is decremented. | |
34d0da31 PP |
156 | @post \p _var_dst is equal to the value of \p _var_src \em before |
157 | you called this macro. | |
b62d3f21 PP |
158 | @post \p _var_src is \c NULL. |
159 | ||
65300d60 | 160 | @sa BT_OBJECT_PUT_REF_AND_RESET(): Calls bt_object_put_ref() on a variable, then sets it to \c NULL. |
b62d3f21 | 161 | */ |
65300d60 | 162 | #define BT_OBJECT_MOVE_REF(_var_dst, _var_src) \ |
b62d3f21 | 163 | do { \ |
65300d60 | 164 | bt_object_put_ref(_var_dst); \ |
b62d3f21 PP |
165 | (_var_dst) = (_var_src); \ |
166 | (_var_src) = NULL; \ | |
e693822d PP |
167 | } while (0) |
168 | ||
b62d3f21 PP |
169 | /** |
170 | @brief Increments the reference count of the Babeltrace object \p obj. | |
171 | ||
172 | @param[in] obj Babeltrace object of which to get a new reference | |
173 | (can be \c NULL). | |
174 | @returns \p obj | |
175 | ||
176 | @post <strong>If \c obj is not \c NULL</strong>, its reference | |
177 | count is incremented. | |
178 | ||
65300d60 | 179 | @sa bt_object_put_ref(): Decrements the reference count of a Babeltrace object. |
b62d3f21 | 180 | */ |
65300d60 | 181 | void *bt_object_get_ref(void *obj); |
de3dd40e | 182 | |
b62d3f21 PP |
183 | /** |
184 | @brief Decrements the reference count of the Babeltrace object | |
185 | \p obj. | |
186 | ||
187 | When the object's reference count reaches 0, the object can no longer | |
188 | be accessed and is considered \em destroyed. | |
189 | ||
190 | @remarks | |
65300d60 | 191 | You should use the BT_OBJECT_PUT_REF_AND_RESET() macro instead of calling bt_object_put_ref() since the |
b62d3f21 PP |
192 | former is generally safer. |
193 | ||
194 | @param[in] obj Babeltrace object of which to drop a reference | |
195 | (can be \c NULL). | |
196 | ||
197 | @post <strong>If \c obj is not \c NULL</strong>, its reference | |
198 | count is decremented. | |
199 | ||
65300d60 PP |
200 | @sa BT_OBJECT_PUT_REF_AND_RESET(): Calls bt_object_put_ref() on a variable, then sets it to \c NULL. |
201 | @sa BT_OBJECT_MOVE_REF(): Transfers the ownership of a Babeltrace object from a | |
b62d3f21 | 202 | variable to another. |
65300d60 | 203 | @sa bt_object_get_ref(): Increments the reference count of a Babeltrace object. |
b62d3f21 | 204 | */ |
65300d60 | 205 | void bt_object_put_ref(void *obj); |
de3dd40e | 206 | |
b62d3f21 PP |
207 | /** |
208 | @} | |
209 | */ | |
210 | ||
26162993 PP |
211 | #ifdef __cplusplus |
212 | } | |
213 | #endif | |
214 | ||
65300d60 | 215 | #endif /* BABELTRACE_OBJECT_H */ |