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
6738 meskes@postgresql.or 13 :CBC 1631125 : ecpg_free(void *ptr)
14 : : {
8400 15 : 1631125 : free(ptr);
16 : 1631125 : }
17 : :
18 : : char *
6738 19 : 1616648 : ecpg_alloc(long size, int lineno)
20 : : {
8400 21 : 1616648 : char *new = (char *) calloc(1L, size);
22 : :
23 [ - + ]: 1616648 : if (!new)
24 : : {
6738 meskes@postgresql.or 25 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8400 26 : 0 : return NULL;
27 : : }
28 : :
3132 peter_e@gmx.net 29 :CBC 1616648 : return new;
30 : : }
31 : :
32 : : char *
6738 meskes@postgresql.or 33 : 5349 : ecpg_realloc(void *ptr, long size, int lineno)
34 : : {
8400 35 : 5349 : char *new = (char *) realloc(ptr, size);
36 : :
37 [ - + ]: 5349 : if (!new)
38 : : {
6738 meskes@postgresql.or 39 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8400 40 : 0 : return NULL;
41 : : }
42 : :
3132 peter_e@gmx.net 43 :CBC 5349 : 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 *
235 michael@paquier.xyz 54 :GNC 5618 : ecpg_strdup(const char *string, int lineno, bool *alloc_failed)
55 : : {
56 : : char *new;
57 : :
7745 meskes@postgresql.or 58 [ - + ]:CBC 5618 : if (string == NULL)
7745 meskes@postgresql.or 59 :UBC 0 : return NULL;
60 : :
7745 meskes@postgresql.or 61 :CBC 5618 : new = strdup(string);
8400 62 [ - + ]: 5618 : if (!new)
63 : : {
235 michael@paquier.xyz 64 [ # # ]:UNC 0 : if (alloc_failed)
65 : 0 : *alloc_failed = true;
6738 meskes@postgresql.or 66 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8400 67 : 0 : return NULL;
68 : : }
69 : :
3132 peter_e@gmx.net 70 :CBC 5618 : 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
6741 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 : 3693 : get_auto_allocs(void)
98 : : {
99 : 3693 : pthread_once(&auto_mem_once, auto_mem_key_init);
100 : 3693 : return (struct auto_mem *) pthread_getspecific(auto_mem_key);
101 : : }
102 : :
103 : : static void
3189 tgl@sss.pgh.pa.us 104 : 1630 : set_auto_allocs(struct auto_mem *am)
105 : : {
6741 meskes@postgresql.or 106 : 1630 : pthread_setspecific(auto_mem_key, am);
107 : 1630 : }
108 : :
109 : : char *
4056 110 : 836 : ecpg_auto_alloc(long size, int lineno)
111 : : {
472 peter@eisentraut.org 112 : 836 : void *ptr = ecpg_alloc(size, lineno);
113 : :
4056 meskes@postgresql.or 114 [ - + ]: 836 : if (!ptr)
4056 meskes@postgresql.or 115 :UBC 0 : return NULL;
116 : :
4056 meskes@postgresql.or 117 [ - + ]:CBC 836 : if (!ecpg_add_mem(ptr, lineno))
118 : : {
4056 meskes@postgresql.or 119 :UBC 0 : ecpg_free(ptr);
120 : 0 : return NULL;
121 : : }
4056 meskes@postgresql.or 122 :CBC 836 : return ptr;
123 : : }
124 : :
125 : : bool
6738 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 : :
4056 130 [ - + ]: 836 : if (!am)
4056 meskes@postgresql.or 131 :UBC 0 : return false;
132 : :
8400 meskes@postgresql.or 133 :CBC 836 : am->pointer = ptr;
6741 134 : 836 : am->next = get_auto_allocs();
135 : 836 : set_auto_allocs(am);
4056 136 : 836 : return true;
137 : : }
138 : :
139 : : void
8400 140 : 78 : ECPGfree_auto_mem(void)
141 : : {
6741 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;
6738 152 : 20 : ecpg_free(act->pointer);
153 : 20 : ecpg_free(act);
6695 bruce@momjian.us 154 [ + + ]: 20 : } while (am);
6741 meskes@postgresql.or 155 : 2 : set_auto_allocs(NULL);
156 : : }
8400 157 : 78 : }
158 : :
159 : : void
6738 160 : 2779 : ecpg_clear_auto_mem(void)
161 : : {
6741 162 : 2779 : struct auto_mem *am = get_auto_allocs();
163 : :
164 : : /* only free our own structure */
165 [ + + ]: 2779 : if (am)
166 : : {
167 : : do
168 : : {
169 : 797 : struct auto_mem *act = am;
170 : :
171 : 797 : am = am->next;
6738 172 : 797 : ecpg_free(act);
6695 bruce@momjian.us 173 [ + + ]: 797 : } while (am);
6741 meskes@postgresql.or 174 : 792 : set_auto_allocs(NULL);
175 : : }
8400 176 : 2779 : }
|