Age Owner 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
5667 meskes 13 CBC 1630905 : ecpg_free(void *ptr)
14 : {
7329 15 1630905 : free(ptr);
16 1630905 : }
17 :
18 : char *
5667 19 1616542 : ecpg_alloc(long size, int lineno)
20 : {
7329 21 1616542 : char *new = (char *) calloc(1L, size);
22 :
23 1616542 : if (!new)
24 : {
5667 meskes 25 UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
7329 26 0 : return NULL;
27 : }
28 :
2061 peter_e 29 CBC 1616542 : return new;
30 : }
31 :
32 : char *
5667 meskes 33 5325 : ecpg_realloc(void *ptr, long size, int lineno)
34 : {
7329 35 5325 : char *new = (char *) realloc(ptr, size);
36 :
37 5325 : if (!new)
38 : {
5667 meskes 39 UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
7329 40 0 : return NULL;
41 : }
42 :
2061 peter_e 43 CBC 5325 : return new;
44 : }
45 :
46 : char *
5667 meskes 47 5591 : ecpg_strdup(const char *string, int lineno)
48 : {
49 : char *new;
50 :
6674 51 5591 : if (string == NULL)
6674 meskes 52 UBC 0 : return NULL;
53 :
6674 meskes 54 CBC 5591 : new = strdup(string);
7329 55 5591 : if (!new)
56 : {
5667 meskes 57 UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
7329 58 0 : return NULL;
59 : }
60 :
2061 peter_e 61 CBC 5591 : return new;
62 : }
63 :
64 : /* keep a list of memory we allocated for the user */
65 : struct auto_mem
66 : {
67 : void *pointer;
68 : struct auto_mem *next;
69 : };
70 :
71 : #ifdef ENABLE_THREAD_SAFETY
72 : static pthread_key_t auto_mem_key;
73 : static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
74 :
75 : static void
5670 meskes 76 16 : auto_mem_destructor(void *arg)
77 : {
78 : (void) arg; /* keep the compiler quiet */
79 16 : ECPGfree_auto_mem();
80 16 : }
81 :
82 : static void
83 56 : auto_mem_key_init(void)
84 : {
85 56 : pthread_key_create(&auto_mem_key, auto_mem_destructor);
86 56 : }
87 :
88 : static struct auto_mem *
89 3662 : get_auto_allocs(void)
90 : {
91 3662 : pthread_once(&auto_mem_once, auto_mem_key_init);
92 3662 : return (struct auto_mem *) pthread_getspecific(auto_mem_key);
93 : }
94 :
95 : static void
2118 tgl 96 1630 : set_auto_allocs(struct auto_mem *am)
97 : {
5670 meskes 98 1630 : pthread_setspecific(auto_mem_key, am);
99 1630 : }
100 : #else
101 : static struct auto_mem *auto_allocs = NULL;
102 :
103 : #define get_auto_allocs() (auto_allocs)
104 : #define set_auto_allocs(am) do { auto_allocs = (am); } while(0)
105 : #endif
106 :
107 : char *
2985 108 836 : ecpg_auto_alloc(long size, int lineno)
109 : {
2878 bruce 110 836 : void *ptr = (void *) ecpg_alloc(size, lineno);
111 :
2985 meskes 112 836 : if (!ptr)
2985 meskes 113 UBC 0 : return NULL;
114 :
2985 meskes 115 CBC 836 : if (!ecpg_add_mem(ptr, lineno))
116 : {
2985 meskes 117 UBC 0 : ecpg_free(ptr);
118 0 : return NULL;
119 : }
2985 meskes 120 CBC 836 : return ptr;
121 : }
122 :
123 : bool
5667 124 836 : ecpg_add_mem(void *ptr, int lineno)
125 : {
126 836 : struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
127 :
2985 128 836 : if (!am)
2985 meskes 129 UBC 0 : return false;
130 :
7329 meskes 131 CBC 836 : am->pointer = ptr;
5670 132 836 : am->next = get_auto_allocs();
133 836 : set_auto_allocs(am);
2985 134 836 : return true;
135 : }
136 :
137 : void
7329 138 70 : ECPGfree_auto_mem(void)
139 : {
5670 140 70 : struct auto_mem *am = get_auto_allocs();
141 :
142 : /* free all memory we have allocated for the user */
143 70 : if (am)
144 : {
145 : do
146 : {
147 20 : struct auto_mem *act = am;
148 :
149 20 : am = am->next;
5667 150 20 : ecpg_free(act->pointer);
151 20 : ecpg_free(act);
5624 bruce 152 20 : } while (am);
5670 meskes 153 2 : set_auto_allocs(NULL);
154 : }
7329 155 70 : }
156 :
157 : void
5667 158 2756 : ecpg_clear_auto_mem(void)
159 : {
5670 160 2756 : struct auto_mem *am = get_auto_allocs();
161 :
162 : /* only free our own structure */
163 2756 : if (am)
164 : {
165 : do
166 : {
167 797 : struct auto_mem *act = am;
168 :
169 797 : am = am->next;
5667 170 797 : ecpg_free(act);
5624 bruce 171 797 : } while (am);
5670 meskes 172 792 : set_auto_allocs(NULL);
173 : }
7329 174 2756 : }
|