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 6524754 : ecpg_free(void *ptr) 14 : { 15 6524754 : free(ptr); 16 6524754 : } 17 : 18 : char * 19 6466640 : ecpg_alloc(long size, int lineno) 20 : { 21 6466640 : char *new = (char *) calloc(1L, size); 22 : 23 6466640 : 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 6466640 : return new; 30 : } 31 : 32 : char * 33 21300 : ecpg_realloc(void *ptr, long size, int lineno) 34 : { 35 21300 : char *new = (char *) realloc(ptr, size); 36 : 37 21300 : 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 21300 : return new; 44 : } 45 : 46 : char * 47 22578 : ecpg_strdup(const char *string, int lineno) 48 : { 49 : char *new; 50 : 51 22578 : if (string == NULL) 52 2 : return NULL; 53 : 54 22576 : new = strdup(string); 55 22576 : if (!new) 56 : { 57 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); 58 0 : return NULL; 59 : } 60 : 61 22576 : 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 : static pthread_key_t auto_mem_key; 72 : static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT; 73 : 74 : static void 75 64 : auto_mem_destructor(void *arg) 76 : { 77 : (void) arg; /* keep the compiler quiet */ 78 64 : ECPGfree_auto_mem(); 79 64 : } 80 : 81 : static void 82 230 : auto_mem_key_init(void) 83 : { 84 230 : pthread_key_create(&auto_mem_key, auto_mem_destructor); 85 230 : } 86 : 87 : static struct auto_mem * 88 14834 : get_auto_allocs(void) 89 : { 90 14834 : pthread_once(&auto_mem_once, auto_mem_key_init); 91 14834 : return (struct auto_mem *) pthread_getspecific(auto_mem_key); 92 : } 93 : 94 : static void 95 6520 : set_auto_allocs(struct auto_mem *am) 96 : { 97 6520 : pthread_setspecific(auto_mem_key, am); 98 6520 : } 99 : 100 : char * 101 3344 : ecpg_auto_alloc(long size, int lineno) 102 : { 103 3344 : void *ptr = (void *) ecpg_alloc(size, lineno); 104 : 105 3344 : if (!ptr) 106 0 : return NULL; 107 : 108 3344 : if (!ecpg_add_mem(ptr, lineno)) 109 : { 110 0 : ecpg_free(ptr); 111 0 : return NULL; 112 : } 113 3344 : return ptr; 114 : } 115 : 116 : bool 117 3344 : ecpg_add_mem(void *ptr, int lineno) 118 : { 119 3344 : struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno); 120 : 121 3344 : if (!am) 122 0 : return false; 123 : 124 3344 : am->pointer = ptr; 125 3344 : am->next = get_auto_allocs(); 126 3344 : set_auto_allocs(am); 127 3344 : return true; 128 : } 129 : 130 : void 131 326 : ECPGfree_auto_mem(void) 132 : { 133 326 : struct auto_mem *am = get_auto_allocs(); 134 : 135 : /* free all memory we have allocated for the user */ 136 326 : if (am) 137 : { 138 : do 139 : { 140 80 : struct auto_mem *act = am; 141 : 142 80 : am = am->next; 143 80 : ecpg_free(act->pointer); 144 80 : ecpg_free(act); 145 80 : } while (am); 146 8 : set_auto_allocs(NULL); 147 : } 148 326 : } 149 : 150 : void 151 11164 : ecpg_clear_auto_mem(void) 152 : { 153 11164 : struct auto_mem *am = get_auto_allocs(); 154 : 155 : /* only free our own structure */ 156 11164 : if (am) 157 : { 158 : do 159 : { 160 3188 : struct auto_mem *act = am; 161 : 162 3188 : am = am->next; 163 3188 : ecpg_free(act); 164 3188 : } while (am); 165 3168 : set_auto_allocs(NULL); 166 : } 167 11164 : }