]> git.ozlabs.org Git - ccan/blob - ccan/take/take.h
take: new module for parameter ownership.
[ccan] / ccan / take / take.h
1 /* CC0 (Public domain) - see LICENSE file for details */
2 #ifndef CCAN_TAKE_H
3 #define CCAN_TAKE_H
4 #include "config.h"
5 #include <stdbool.h>
6
7 /**
8  * take - record a pointer to be consumed by the function its handed to.
9  * @p: the pointer to mark, or NULL.
10  *
11  * This marks a pointer object to be freed by the called function,
12  * which is extremely useful for chaining functions.  It works on
13  * NULL, for pass-through error handling.
14  */
15 #define take(p) (take_typeof(p) take_((p)))
16
17 /**
18  * taken - check (and un-take) a pointer was passed with take()
19  * @p: the pointer to check.
20  *
21  * A function which accepts take() arguments uses this to see if it
22  * should own the pointer; it will be removed from the take list, so
23  * this only returns true once.
24  *
25  * Example:
26  *      // Silly routine to add 1
27  *      static int *add_one(const int *num)
28  *      {
29  *              int *ret;
30  *              if (taken(num))
31  *                      ret = (int *)num;
32  *              else
33  *                      ret = malloc(sizeof(int));
34  *              if (ret)
35  *                      *ret = (*num) + 1;
36  *              return ret;
37  *      }
38  */
39 bool taken(const void *p);
40
41 /**
42  * is_taken - check if a pointer was passed with take()
43  * @p: the pointer to check.
44  *
45  * This is like the above, but doesn't remove it from the taken list.
46  *
47  * Example:
48  *      // Silly routine to add 1: doesn't handle taken args!
49  *      static int *add_one_notake(const int *num)
50  *      {
51  *              int *ret = malloc(sizeof(int));
52  *              assert(!is_taken(num));
53  *              if (ret)
54  *                      *ret = (*num) + 1;
55  *              return ret;
56  *      }
57  */
58 bool is_taken(const void *p);
59
60 /**
61  * taken_any - are there any taken pointers?
62  *
63  * Mainly useful for debugging take() leaks.
64  *
65  * Example:
66  *      static void cleanup(void)
67  *      {
68  *              assert(!taken_any());
69  *      }
70  */
71 bool taken_any(void);
72
73 /**
74  * take_cleanup - remove all taken pointers from list.
75  *
76  * This is useful in atexit() handlers for valgrind-style leak detection.
77  *
78  * Example:
79  *      static void cleanup2(void)
80  *      {
81  *              take_cleanup();
82  *      }
83  */
84 void take_cleanup(void);
85
86 /**
87  * take_allocfail - set function to call if we can't reallocated taken array.
88  * @fn: the function.
89  *
90  * If this is not set, then if the array reallocation fails, the
91  * pointer won't be marked taken().  If @fn returns, it is expected to
92  * free the pointer; we return NULL from take() and the function handles
93  * it like any allocation failure.
94  *
95  * Example:
96  *      static void free_on_fail(const void *p)
97  *      {
98  *              free((void *)p);
99  *      }
100  *
101  *      static void init(void)
102  *      {
103  *              take_allocfail(free_on_fail);
104  *      }
105  */
106 void take_allocfail(void (*fn)(const void *p));
107
108 /* Private functions */
109 #if HAVE_TYPEOF
110 #define take_typeof(ptr) (__typeof__(ptr))
111 #else
112 #define take_typeof(ptr)
113 #endif
114
115 void *take_(const void *p);
116 #endif /* CCAN_TAKE_H */