Line data Source code
1 : /* src/interfaces/ecpg/ecpglib/memory.c */
2 :
3 : #define POSTGRES_ECPG_INTERNAL
4 : #include "postgres_fe.h"
5 :
6 : #include "ecpg-pthread-win32.h"
7 : #include "ecpgerrno.h"
8 : #include "ecpglib.h"
9 : #include "ecpglib_extern.h"
10 : #include "ecpgtype.h"
11 :
12 : void
13 3262327 : ecpg_free(void *ptr)
14 : {
15 3262327 : free(ptr);
16 3262327 : }
17 :
18 : char *
19 3233330 : ecpg_alloc(long size, int lineno)
20 : {
21 3233330 : char *new = (char *) calloc(1L, size);
22 :
23 3233330 : if (!new)
24 : {
25 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
26 0 : return NULL;
27 : }
28 :
29 3233330 : return new;
30 : }
31 :
32 : char *
33 10698 : ecpg_realloc(void *ptr, long size, int lineno)
34 : {
35 10698 : char *new = (char *) realloc(ptr, size);
36 :
37 10698 : if (!new)
38 : {
39 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
40 0 : return NULL;
41 : }
42 :
43 10698 : return new;
44 : }
45 :
46 : /*
47 : * Wrapper for strdup(), with NULL in input treated as a correct case.
48 : *
49 : * "alloc_failed" can be optionally specified by the caller to check for
50 : * allocation failures. The caller is responsible for its initialization,
51 : * as ecpg_strdup() may be called repeatedly across multiple allocations.
52 : */
53 : char *
54 11276 : ecpg_strdup(const char *string, int lineno, bool *alloc_failed)
55 : {
56 : char *new;
57 :
58 11276 : if (string == NULL)
59 0 : return NULL;
60 :
61 11276 : new = strdup(string);
62 11276 : if (!new)
63 : {
64 0 : if (alloc_failed)
65 0 : *alloc_failed = true;
66 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
67 0 : return NULL;
68 : }
69 :
70 11276 : return new;
71 : }
72 :
73 : /* keep a list of memory we allocated for the user */
74 : struct auto_mem
75 : {
76 : void *pointer;
77 : struct auto_mem *next;
78 : };
79 :
80 : static pthread_key_t auto_mem_key;
81 : static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
82 :
83 : static void
84 32 : auto_mem_destructor(void *arg)
85 : {
86 : (void) arg; /* keep the compiler quiet */
87 32 : ECPGfree_auto_mem();
88 32 : }
89 :
90 : static void
91 115 : auto_mem_key_init(void)
92 : {
93 115 : pthread_key_create(&auto_mem_key, auto_mem_destructor);
94 115 : }
95 :
96 : static struct auto_mem *
97 7405 : get_auto_allocs(void)
98 : {
99 7405 : pthread_once(&auto_mem_once, auto_mem_key_init);
100 7405 : return (struct auto_mem *) pthread_getspecific(auto_mem_key);
101 : }
102 :
103 : static void
104 3260 : set_auto_allocs(struct auto_mem *am)
105 : {
106 3260 : pthread_setspecific(auto_mem_key, am);
107 3260 : }
108 :
109 : char *
110 1672 : ecpg_auto_alloc(long size, int lineno)
111 : {
112 1672 : void *ptr = ecpg_alloc(size, lineno);
113 :
114 1672 : if (!ptr)
115 0 : return NULL;
116 :
117 1672 : if (!ecpg_add_mem(ptr, lineno))
118 : {
119 0 : ecpg_free(ptr);
120 0 : return NULL;
121 : }
122 1672 : return ptr;
123 : }
124 :
125 : bool
126 1672 : ecpg_add_mem(void *ptr, int lineno)
127 : {
128 1672 : struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
129 :
130 1672 : if (!am)
131 0 : return false;
132 :
133 1672 : am->pointer = ptr;
134 1672 : am->next = get_auto_allocs();
135 1672 : set_auto_allocs(am);
136 1672 : return true;
137 : }
138 :
139 : void
140 163 : ECPGfree_auto_mem(void)
141 : {
142 163 : struct auto_mem *am = get_auto_allocs();
143 :
144 : /* free all memory we have allocated for the user */
145 163 : if (am)
146 : {
147 : do
148 : {
149 40 : struct auto_mem *act = am;
150 :
151 40 : am = am->next;
152 40 : ecpg_free(act->pointer);
153 40 : ecpg_free(act);
154 40 : } while (am);
155 4 : set_auto_allocs(NULL);
156 : }
157 163 : }
158 :
159 : void
160 5570 : ecpg_clear_auto_mem(void)
161 : {
162 5570 : struct auto_mem *am = get_auto_allocs();
163 :
164 : /* only free our own structure */
165 5570 : if (am)
166 : {
167 : do
168 : {
169 1594 : struct auto_mem *act = am;
170 :
171 1594 : am = am->next;
172 1594 : ecpg_free(act);
173 1594 : } while (am);
174 1584 : set_auto_allocs(NULL);
175 : }
176 5570 : }
|