Line data Source code
1 : /*
2 : SSSD
3 :
4 : Simple reference counting wrappers for talloc.
5 :
6 : Authors:
7 : Martin Nagy <mnagy@redhat.com>
8 :
9 : Copyright (C) Red Hat, Inc 2009
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include <talloc.h>
26 :
27 : #include "refcount.h"
28 : #include "util/util.h"
29 :
30 : struct wrapper {
31 : int *refcount;
32 : void *ptr;
33 : };
34 :
35 : static int
36 395 : refcount_destructor(struct wrapper *wrapper)
37 : {
38 395 : (*wrapper->refcount)--;
39 395 : if (*wrapper->refcount == 0) {
40 50 : talloc_free(wrapper->ptr);
41 : };
42 :
43 395 : return 0;
44 : }
45 :
46 : void *
47 50 : _rc_alloc(const void *context, size_t size, size_t refcount_offset,
48 : const char *type_name)
49 : {
50 : struct wrapper *wrapper;
51 : char *refcount_pos;
52 :
53 50 : wrapper = talloc(context, struct wrapper);
54 50 : if (wrapper == NULL) {
55 0 : return NULL;
56 : }
57 :
58 50 : wrapper->ptr = talloc_named_const(NULL, size, type_name);
59 50 : if (wrapper->ptr == NULL) {
60 0 : talloc_free(wrapper);
61 0 : return NULL;
62 : };
63 :
64 50 : refcount_pos = (char *)wrapper->ptr + refcount_offset;
65 50 : wrapper->refcount = DISCARD_ALIGN(refcount_pos, int *);
66 50 : *wrapper->refcount = 1;
67 :
68 50 : talloc_set_destructor(wrapper, refcount_destructor);
69 :
70 50 : return wrapper->ptr;
71 : }
72 :
73 : void *
74 345 : _rc_reference(const void *context, size_t refcount_offset, void *source)
75 : {
76 : struct wrapper *wrapper;
77 : char *refcount_pos;
78 :
79 345 : wrapper = talloc(context, struct wrapper);
80 345 : if (wrapper == NULL) {
81 0 : return NULL;
82 : }
83 :
84 345 : wrapper->ptr = source;
85 345 : refcount_pos = (char *)wrapper->ptr + refcount_offset;
86 345 : wrapper->refcount = DISCARD_ALIGN(refcount_pos, int *);
87 345 : (*wrapper->refcount)++;
88 :
89 345 : talloc_set_destructor(wrapper, refcount_destructor);
90 :
91 345 : return wrapper->ptr;
92 : }
|