Imported Upstream version 1.5.0
[platform/upstream/augeas.git] / src / ref.h
1 /*
2  * ref.h: reference counting macros
3  *
4  * Copyright (C) 2007-2015 David Lutterkort
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  *
20  * Author: David Lutterkort <dlutter@redhat.com>
21  */
22
23 #ifndef REF_H_
24 #define REF_H_
25
26 #include <limits.h>
27 #include <stddef.h>
28
29 /* Reference counting for pointers to structs with a REF field of type ref_t
30  *
31  * When a pointer to such a struct is passed into a function that stores
32  * it, the function can either "receive ownership", meaning it does not
33  * increment the reference count, or it can "take ownership", meaning it
34  * increments the reference count. In the first case, the reference is now
35  * owned by wherever the function stored it, and not the caller anymore; in
36  * the second case, the caller and whereever the reference was stored both
37  * own the reference.
38  */
39 // FIXME: This is not threadsafe; incr/decr ref needs to be protected
40
41 #define REF_MAX UINT_MAX
42
43 typedef unsigned int ref_t;
44
45 int ref_make_ref(void *ptrptr, size_t size, size_t ref_ofs);
46
47 #define make_ref(var)                                           \
48     ref_make_ref(&(var), sizeof(*(var)), offsetof(typeof(*(var)), ref))
49
50 #define make_ref_err(var) if (make_ref(var) < 0) goto error
51
52 #define ref(s) (((s) == NULL || (s)->ref == REF_MAX) ? (s) : ((s)->ref++, (s)))
53
54 #define unref(s, t)                                                     \
55     do {                                                                \
56         if ((s) != NULL && (s)->ref != REF_MAX) {                       \
57             assert((s)->ref > 0);                                       \
58             if (--(s)->ref == 0) {                                      \
59                 /*memset(s, 255, sizeof(*s));*/                         \
60                 free_##t(s);                                            \
61             }                                                           \
62         }                                                               \
63         (s) = NULL;                                                     \
64     } while(0)
65
66 /* Make VAR uncollectable and pin it in memory for eternity */
67 #define ref_pin(var)   (var)->ref = REF_MAX
68
69 #endif
70
71
72 /*
73  * Local variables:
74  *  indent-tabs-mode: nil
75  *  c-indent-level: 4
76  *  c-basic-offset: 4
77  *  tab-width: 4
78  * End:
79  */