Age Owner Branch data TLA 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
6548 meskes@postgresql.or 13 :CBC 1631150 : ecpg_free(void *ptr)
14 : : {
8210 15 : 1631150 : free(ptr);
16 : 1631150 : }
17 : :
18 : : char *
6548 19 : 1616643 : ecpg_alloc(long size, int lineno)
20 : : {
8210 21 : 1616643 : char *new = (char *) calloc(1L, size);
22 : :
23 [ - + ]: 1616643 : if (!new)
24 : : {
6548 meskes@postgresql.or 25 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8210 26 : 0 : return NULL;
27 : : }
28 : :
2942 peter_e@gmx.net 29 :CBC 1616643 : return new;
30 : : }
31 : :
32 : : char *
6548 meskes@postgresql.or 33 : 5325 : ecpg_realloc(void *ptr, long size, int lineno)
34 : : {
8210 35 : 5325 : char *new = (char *) realloc(ptr, size);
36 : :
37 [ - + ]: 5325 : if (!new)
38 : : {
6548 meskes@postgresql.or 39 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8210 40 : 0 : return NULL;
41 : : }
42 : :
2942 peter_e@gmx.net 43 :CBC 5325 : 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 *
45 michael@paquier.xyz 54 :GNC 5624 : ecpg_strdup(const char *string, int lineno, bool *alloc_failed)
55 : : {
56 : : char *new;
57 : :
7555 meskes@postgresql.or 58 [ - + ]:CBC 5624 : if (string == NULL)
7555 meskes@postgresql.or 59 :UBC 0 : return NULL;
60 : :
7555 meskes@postgresql.or 61 :CBC 5624 : new = strdup(string);
8210 62 [ - + ]: 5624 : if (!new)
63 : : {
45 michael@paquier.xyz 64 [ # # ]:UNC 0 : if (alloc_failed)
65 : 0 : *alloc_failed = true;
6548 meskes@postgresql.or 66 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8210 67 : 0 : return NULL;
68 : : }
69 : :
2942 peter_e@gmx.net 70 :CBC 5624 : 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
6551 meskes@postgresql.or 84 : 16 : auto_mem_destructor(void *arg)
85 : : {
86 : : (void) arg; /* keep the compiler quiet */
87 : 16 : ECPGfree_auto_mem();
88 : 16 : }
89 : :
90 : : static void
91 : 57 : auto_mem_key_init(void)
92 : : {
93 : 57 : pthread_key_create(&auto_mem_key, auto_mem_destructor);
94 : 57 : }
95 : :
96 : : static struct auto_mem *
97 : 3699 : get_auto_allocs(void)
98 : : {
99 : 3699 : pthread_once(&auto_mem_once, auto_mem_key_init);
100 : 3699 : return (struct auto_mem *) pthread_getspecific(auto_mem_key);
101 : : }
102 : :
103 : : static void
2999 tgl@sss.pgh.pa.us 104 : 1630 : set_auto_allocs(struct auto_mem *am)
105 : : {
6551 meskes@postgresql.or 106 : 1630 : pthread_setspecific(auto_mem_key, am);
107 : 1630 : }
108 : :
109 : : char *
3866 110 : 836 : ecpg_auto_alloc(long size, int lineno)
111 : : {
282 peter@eisentraut.org 112 : 836 : void *ptr = ecpg_alloc(size, lineno);
113 : :
3866 meskes@postgresql.or 114 [ - + ]: 836 : if (!ptr)
3866 meskes@postgresql.or 115 :UBC 0 : return NULL;
116 : :
3866 meskes@postgresql.or 117 [ - + ]:CBC 836 : if (!ecpg_add_mem(ptr, lineno))
118 : : {
3866 meskes@postgresql.or 119 :UBC 0 : ecpg_free(ptr);
120 : 0 : return NULL;
121 : : }
3866 meskes@postgresql.or 122 :CBC 836 : return ptr;
123 : : }
124 : :
125 : : bool
6548 126 : 836 : ecpg_add_mem(void *ptr, int lineno)
127 : : {
128 : 836 : struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
129 : :
3866 130 [ - + ]: 836 : if (!am)
3866 meskes@postgresql.or 131 :UBC 0 : return false;
132 : :
8210 meskes@postgresql.or 133 :CBC 836 : am->pointer = ptr;
6551 134 : 836 : am->next = get_auto_allocs();
135 : 836 : set_auto_allocs(am);
3866 136 : 836 : return true;
137 : : }
138 : :
139 : : void
8210 140 : 78 : ECPGfree_auto_mem(void)
141 : : {
6551 142 : 78 : struct auto_mem *am = get_auto_allocs();
143 : :
144 : : /* free all memory we have allocated for the user */
145 [ + + ]: 78 : if (am)
146 : : {
147 : : do
148 : : {
149 : 20 : struct auto_mem *act = am;
150 : :
151 : 20 : am = am->next;
6548 152 : 20 : ecpg_free(act->pointer);
153 : 20 : ecpg_free(act);
6505 bruce@momjian.us 154 [ + + ]: 20 : } while (am);
6551 meskes@postgresql.or 155 : 2 : set_auto_allocs(NULL);
156 : : }
8210 157 : 78 : }
158 : :
159 : : void
6548 160 : 2785 : ecpg_clear_auto_mem(void)
161 : : {
6551 162 : 2785 : struct auto_mem *am = get_auto_allocs();
163 : :
164 : : /* only free our own structure */
165 [ + + ]: 2785 : if (am)
166 : : {
167 : : do
168 : : {
169 : 797 : struct auto_mem *act = am;
170 : :
171 : 797 : am = am->next;
6548 172 : 797 : ecpg_free(act);
6505 bruce@momjian.us 173 [ + + ]: 797 : } while (am);
6551 meskes@postgresql.or 174 : 792 : set_auto_allocs(NULL);
175 : : }
8210 176 : 2785 : }
|