Fixed wrealloc() to be consistent with the wmalloc() behaviour when it cannot
[wmaker-crm.git] / WINGs / memory.c
blobdbe60c2a5f8145316b583cab28a6a51f410e8cbe
1 /*
2 * Window Maker miscelaneous function library
3 *
4 * Copyright (c) 1997 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "../src/config.h"
24 #include "WUtil.h"
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <signal.h>
34 #ifdef TEST_WITH_GC
35 #include <gc/gc.h>
36 #endif
38 #ifndef False
39 # define False 0
40 #endif
41 #ifndef True
42 # define True 1
43 #endif
46 static void
47 defaultHandler(int bla)
49 if (bla)
50 kill(getpid(), SIGABRT);
51 else
52 exit(1);
56 static waborthandler *aborthandler = (waborthandler*)defaultHandler;
58 #define wAbort(a) (*aborthandler)(a)
61 waborthandler*
62 wsetabort(waborthandler *handler)
64 waborthandler *old = aborthandler;
66 aborthandler = handler;
68 return old;
73 static int Aborting=0; /* if we're in the middle of an emergency exit */
76 static WMHashTable *table = NULL;
79 void *wmalloc(size_t size)
81 void *tmp;
83 #ifdef TEST_WITH_GC
84 tmp = GC_malloc(size);
85 #else
86 tmp = malloc(size);
87 #endif
88 if (tmp == NULL) {
89 wwarning("malloc() failed. Retrying after 2s.");
90 sleep(2);
91 #ifdef TEST_WITH_GC
92 tmp = GC_malloc(size);
93 #else
94 tmp = malloc(size);
95 #endif
96 if (tmp == NULL) {
97 if (Aborting) {
98 fputs("Really Bad Error: recursive malloc() failure.", stderr);
99 exit(-1);
100 } else {
101 wfatal("virtual memory exhausted");
102 Aborting=1;
103 wAbort(False);
107 return tmp;
111 void *wrealloc(void *ptr, size_t newsize)
113 void *nptr;
115 if (!ptr) {
116 nptr = wmalloc(newsize);
117 } else {
118 #ifdef TEST_WITH_GC
119 nptr = GC_realloc(ptr, newsize);
120 #else
121 nptr = realloc(ptr, newsize);
122 #endif
123 if (nptr==NULL) {
124 wwarning("realloc() failed. Retrying after 2s.");
125 sleep(2);
126 #ifdef TEST_WITH_GC
127 nptr = GC_realloc(ptr, newsize);
128 #else
129 nptr = realloc(ptr, newsize);
130 #endif
131 if (nptr == NULL) {
132 if (Aborting) {
133 fputs("Really Bad Error: recursive realloc() failure.",
134 stderr);
135 exit(-1);
136 } else {
137 wfatal("virtual memory exhausted");
138 Aborting=1;
139 wAbort(False);
144 return nptr;
148 void*
149 wretain(void *ptr)
151 int *refcount;
153 if (!table) {
154 table = WMCreateHashTable(WMIntHashCallbacks);
157 refcount = WMHashGet(table, ptr);
158 if (!refcount) {
159 refcount = wmalloc(sizeof(int));
160 *refcount = 1;
161 WMHashInsert(table, ptr, refcount);
162 #ifdef VERBOSE
163 printf("== %i (%p)\n", *refcount, ptr);
164 #endif
165 } else {
166 (*refcount)++;
167 #ifdef VERBOSE
168 printf("+ %i (%p)\n", *refcount, ptr);
169 #endif
172 return ptr;
177 void
178 wfree(void *ptr)
180 #ifdef TEST_WITH_GC
181 GC_free(ptr);
182 #else
183 free(ptr);
184 #endif
189 void
190 wrelease(void *ptr)
192 int *refcount;
194 refcount = WMHashGet(table, ptr);
195 if (!refcount) {
196 wwarning("trying to release unexisting data %p", ptr);
197 } else {
198 (*refcount)--;
199 if (*refcount < 1) {
200 #ifdef VERBOSE
201 printf("RELEASING %p\n", ptr);
202 #endif
203 WMHashRemove(table, ptr);
204 wfree(refcount);
205 wfree(ptr);
207 #ifdef VERBOSE
208 else {
209 printf("- %i (%p)\n", *refcount, ptr);
211 #endif
216 char*
217 wstrdup(char *str)
219 assert(str!=NULL);
221 return strcpy(wmalloc(strlen(str)+1), str);
225 char*
226 wstrappend(char *dst, char *src)
228 char *str;
230 if (!dst)
231 return wstrdup(src);
232 else if (!src)
233 return wstrdup(dst);
235 str = wmalloc(strlen(dst)+strlen(src)+1);
236 strcpy(str, dst);
237 strcat(str, src);
239 return str;