Asterisk - The Open Source Telephony Project GIT-master-67613d1
astobj2_container_private.h
Go to the documentation of this file.
1/*
2 * astobj2 - replacement containers for asterisk data structures.
3 *
4 * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
5 *
6 * See http://www.asterisk.org for more information about
7 * the Asterisk project. Please do not directly contact
8 * any of the maintainers of this project for assistance;
9 * the project provides a web site, mailing lists and IRC
10 * channels for your use.
11 *
12 * This program is free software, distributed under the terms of
13 * the GNU General Public License Version 2. See the LICENSE file
14 * at the top of the source tree.
15 */
16
17/*! \file
18 *
19 * \brief Common, private definitions for astobj2 containers.
20 *
21 * \author Richard Mudgett <rmudgett@digium.com>
22 */
23
24#ifndef ASTOBJ2_CONTAINER_PRIVATE_H_
25#define ASTOBJ2_CONTAINER_PRIVATE_H_
26
27#include "asterisk/astobj2.h"
28
29/*!
30 * \internal
31 * \brief Enum for internal_ao2_unlink_node.
32 */
34 /*! Remove the node from the object's weak link list
35 * OR unref the object if it's a strong reference. */
37 /*! Modified unlink_object to skip the unref of the object. */
39 /*! Unref the node. */
41 /*! Decrement the container's element count. */
43};
44
48};
49
51 /*! The node was inserted into the container. */
53 /*! The node object replaced an existing node object. */
55 /*! The node was rejected (duplicate). */
57};
58
59/*! Allow enough room for container specific traversal state structs */
60#define AO2_TRAVERSAL_STATE_SIZE 100
61
62/*!
63 * \brief Generic container node.
64 *
65 * \details This is the base container node type that contains
66 * values common to all container nodes.
67 */
69 /*! Stored object in node. */
70 void *obj;
71 /*! Container holding the node. (Does not hold a reference.) */
73 /*! TRUE if the node is linked into the container. */
74 unsigned int is_linked:1;
75};
76
77/*!
78 * \brief Destroy this container.
79 *
80 * \param self Container to operate upon.
81 */
82typedef void (*ao2_container_destroy_fn)(struct ao2_container *self);
83
84/*!
85 * \brief Create an empty copy of this container.
86 *
87 * \param self Container to operate upon.
88 * \param tag used for debugging.
89 * \param file Debug file name invoked from
90 * \param line Debug line invoked from
91 * \param func Debug function name invoked from
92 *
93 * \return empty-container on success.
94 * \retval NULL on error.
95 */
96typedef struct ao2_container *(*ao2_container_alloc_empty_clone_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func);
97
98/*!
99 * \brief Create a new container node.
100 *
101 * \param self Container to operate upon.
102 * \param obj_new Object to put into the node.
103 * \param tag used for debugging.
104 * \param file Debug file name invoked from
105 * \param line Debug line invoked from
106 * \param func Debug function name invoked from
107 *
108 * \return initialized-node on success.
109 * \retval NULL on error.
110 */
111typedef struct ao2_container_node *(*ao2_container_new_node_fn)(struct ao2_container *self, void *obj_new, const char *tag, const char *file, int line, const char *func);
112
113/*!
114 * \brief Insert a node into this container.
115 *
116 * \param self Container to operate upon.
117 * \param node Container node to insert into the container.
118 *
119 * \return enum ao2_container_insert value.
120 */
122
123/*!
124 * \brief Find the first container node in a traversal.
125 *
126 * \param self Container to operate upon.
127 * \param flags search_flags to control traversing the container
128 * \param arg Comparison callback arg parameter.
129 * \param v_state Traversal state to restart container traversal.
130 *
131 * \return node-ptr of found node (Reffed).
132 * \retval NULL when no node found.
133 */
134typedef struct ao2_container_node *(*ao2_container_find_first_fn)(struct ao2_container *self, enum search_flags flags, void *arg, void *v_state);
135
136/*!
137 * \brief Find the next container node in a traversal.
138 *
139 * \param self Container to operate upon.
140 * \param v_state Traversal state to restart container traversal.
141 * \param prev Previous node returned by the traversal search functions.
142 * The ref ownership is passed back to this function.
143 *
144 * \return node-ptr of found node (Reffed).
145 * \retval NULL when no node found.
146 */
147typedef struct ao2_container_node *(*ao2_container_find_next_fn)(struct ao2_container *self, void *v_state, struct ao2_container_node *prev);
148
149/*!
150 * \brief Cleanup the container traversal state.
151 *
152 * \param v_state Traversal state to cleanup.
153 */
154typedef void (*ao2_container_find_cleanup_fn)(void *v_state);
155
156/*!
157 * \brief Find the next non-empty iteration node in the container.
158 *
159 * \param self Container to operate upon.
160 * \param prev Previous node returned by the iterator.
161 * \param flags search_flags to control iterating the container.
162 * Only AO2_ITERATOR_DESCENDING is useful by the method.
163 *
164 * \note The container is already locked.
165 *
166 * \return node on success.
167 * \retval NULL on error or no more nodes in the container.
168 */
169typedef struct ao2_container_node *(*ao2_iterator_next_fn)(struct ao2_container *self, struct ao2_container_node *prev, enum ao2_iterator_flags flags);
170
171/*!
172 * \brief Display contents of the specified container.
173 *
174 * \param self Container to dump.
175 * \param where User data needed by prnt to determine where to put output.
176 * \param prnt Print output callback function to use.
177 * \param prnt_obj Callback function to print the given object's key. (NULL if not available)
178 */
179typedef void (*ao2_container_display)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj);
180
181/*!
182 * \brief Display statistics of the specified container.
183 *
184 * \param self Container to display statistics.
185 * \param where User data needed by prnt to determine where to put output.
186 * \param prnt Print output callback function to use.
187 *
188 * \note The container is already locked for reading.
189 */
190typedef void (*ao2_container_statistics)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt);
191
192/*!
193 * \brief Perform an integrity check on the specified container.
194 *
195 * \param self Container to check integrity.
196 *
197 * \note The container is already locked for reading.
198 *
199 * \retval 0 on success.
200 * \retval -1 on error.
201 */
202typedef int (*ao2_container_integrity)(struct ao2_container *self);
203
204/*!
205 * \internal
206 * \brief Increment the container linked object statistic.
207 * \since 12.4.0
208 *
209 * \param container Container to operate upon.
210 * \param node Container node linking object to.
211 */
213
214/*!
215 * \internal
216 * \brief Decrement the container linked object statistic.
217 * \since 12.4.0
218 *
219 * \param container Container to operate upon.
220 * \param node Container node unlinking object from.
221 */
223
224/*! Container virtual methods template. */
226 /*! Destroy this container. */
228 /*! \brief Create an empty copy of this container. */
230 /*! Create a new container node. */
232 /*! Insert a node into this container. */
234 /*! Traverse the container, find the first node. */
236 /*! Traverse the container, find the next node. */
238 /*! Traverse the container, cleanup state. */
240 /*! Find the next iteration element in the container. */
242#if defined(AO2_DEBUG)
243 /*! Increment the container linked object statistic. */
244 ao2_link_node_stat_fn link_stat;
245 /*! Decrement the container linked object statistic. */
246 ao2_unlink_node_stat_fn unlink_stat;
247 /*! Display container contents. (Method for debug purposes) */
249 /*! Display container debug statistics. (Method for debug purposes) */
251 /*! Perform an integrity check on the container. (Method for debug purposes) */
252 ao2_container_integrity integrity;
253#endif /* defined(AO2_DEBUG) */
254};
255
256/*!
257 * \brief Generic container type.
258 *
259 * \details This is the base container type that contains values
260 * common to all container types.
261 *
262 * \todo Linking and unlinking container objects is typically
263 * expensive, as it involves a malloc()/free() of a small object
264 * which is very inefficient. To optimize this, we can allocate
265 * larger arrays of container nodes when we run out of them, and
266 * then manage our own freelist. This will be more efficient as
267 * we can do the freelist management while we hold the lock
268 * (that we need anyway).
269 */
271 /*! Container virtual method table. */
273 /*! Container sort function if the container is sorted. */
275 /*! Container traversal matching function for ao2_find. */
277 /*! The container option flags */
278 uint32_t options;
279 /*! Number of elements in the container. */
281#if defined(AO2_DEBUG)
282 /*! Number of nodes in the container. */
283 int nodes;
284 /*! Maximum number of empty nodes in the container. (nodes - elements) */
285 int max_empty_nodes;
286#endif /* defined(AO2_DEBUG) */
287 /*!
288 * \brief TRUE if the container is being destroyed.
289 *
290 * \note The destruction traversal should override any requested
291 * search order to do the most efficient order for destruction.
292 *
293 * \note There should not be any empty nodes in the container
294 * during destruction. If there are then an error needs to be
295 * issued about container node reference leaks.
296 */
297 unsigned int destroying:1;
298};
299
300/*!
301 * \internal
302 * \brief Unlink a node from this container.
303 *
304 * \param node Node to operate upon.
305 * \param flags ao2_unlink_node_flags governing behavior.
306 *
307 * \retval 0 on errors.
308 * \retval 1 on success.
309 */
310#define __container_unlink_node(node, flags) \
311 __container_unlink_node_debug(node, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
312int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flags,
313 const char *tag, const char *file, int line, const char *func);
314
315void container_destruct(void *_c);
316int container_init(void);
317
318#endif /* ASTOBJ2_CONTAINER_PRIVATE_H_ */
void() ao2_prnt_obj_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
Print object key.
Definition: astobj2.h:1445
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
Definition: astobj2.h:1226
ao2_iterator_flags
Definition: astobj2.h:1835
int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)
Type of generic container sort function.
Definition: astobj2.h:1276
search_flags
Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.
Definition: astobj2.h:1034
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
Definition: astobj2.h:1435
void(* ao2_container_statistics)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt)
Display statistics of the specified container.
@ AO2_CALLBACK_DEFAULT
@ AO2_CALLBACK_WITH_DATA
void(* ao2_unlink_node_stat_fn)(struct ao2_container *container, struct ao2_container_node *node)
void(* ao2_container_destroy_fn)(struct ao2_container *self)
Destroy this container.
int(* ao2_container_integrity)(struct ao2_container *self)
Perform an integrity check on the specified container.
struct ao2_container_node *(* ao2_container_new_node_fn)(struct ao2_container *self, void *obj_new, const char *tag, const char *file, int line, const char *func)
Create a new container node.
void(* ao2_container_display)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
Display contents of the specified container.
struct ao2_container_node *(* ao2_iterator_next_fn)(struct ao2_container *self, struct ao2_container_node *prev, enum ao2_iterator_flags flags)
Find the next non-empty iteration node in the container.
struct ao2_container_node *(* ao2_container_find_first_fn)(struct ao2_container *self, enum search_flags flags, void *arg, void *v_state)
Find the first container node in a traversal.
int container_init(void)
struct ao2_container_node *(* ao2_container_find_next_fn)(struct ao2_container *self, void *v_state, struct ao2_container_node *prev)
Find the next container node in a traversal.
void container_destruct(void *_c)
struct ao2_container *(* ao2_container_alloc_empty_clone_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func)
Create an empty copy of this container.
@ AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED
@ AO2_CONTAINER_INSERT_NODE_REJECTED
@ AO2_CONTAINER_INSERT_NODE_INSERTED
int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flags, const char *tag, const char *file, int line, const char *func)
void(* ao2_link_node_stat_fn)(struct ao2_container *container, struct ao2_container_node *node)
void(* ao2_container_find_cleanup_fn)(void *v_state)
Cleanup the container traversal state.
@ AO2_UNLINK_NODE_UNREF_NODE
@ AO2_UNLINK_NODE_UNLINK_OBJECT
@ AO2_UNLINK_NODE_DEC_COUNT
@ AO2_UNLINK_NODE_NOUNREF_OBJECT
enum ao2_container_insert(* ao2_container_insert_fn)(struct ao2_container *self, struct ao2_container_node *node)
Insert a node into this container.
static struct ao2_container * nodes
All the nodes that we're aware of.
Definition: res_corosync.c:65
struct ao2_container * container
Definition: res_fax.c:501
ao2_container_insert_fn insert
ao2_container_alloc_empty_clone_fn alloc_empty_clone
Create an empty copy of this container.
ao2_iterator_next_fn iterator_next
ao2_container_find_cleanup_fn traverse_cleanup
ao2_container_new_node_fn new_node
ao2_container_destroy_fn destroy
ao2_container_find_next_fn traverse_next
ao2_container_find_first_fn traverse_first
Generic container node.
struct ao2_container * my_container
Generic container type.
ao2_callback_fn * cmp_fn
unsigned int destroying
TRUE if the container is being destroyed.
const struct ao2_container_methods * v_table
Definition: test_heap.c:38