Unused wsmap, begone!
[wmaker-crm.git] / WINGs / memory.c
blob9d770b0b2d896c368da33c2e5858e893fc530fd3
1 /*
2 * Window Maker miscelaneous function library
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
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.
21 #include "wconfig.h"
22 #include "WUtil.h"
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <assert.h>
30 #include <signal.h>
32 #ifdef TEST_WITH_GC
33 #include <gc/gc.h>
34 #endif
36 #ifndef False
37 # define False 0
38 #endif
39 #ifndef True
40 # define True 1
41 #endif
43 static void defaultHandler(int bla)
45 if (bla)
46 kill(getpid(), SIGABRT);
47 else
48 exit(1);
51 static waborthandler *aborthandler = (waborthandler *) defaultHandler;
53 #define wAbort(a) (*aborthandler)(a)
55 waborthandler *wsetabort(waborthandler * handler)
57 waborthandler *old = aborthandler;
59 aborthandler = handler;
61 return old;
64 static int Aborting = 0; /* if we're in the middle of an emergency exit */
66 static WMHashTable *table = NULL;
68 void *wmalloc(size_t size)
70 void *tmp;
72 assert(size > 0);
74 #ifdef TEST_WITH_GC
75 tmp = GC_malloc(size);
76 #else
77 tmp = malloc(size);
78 #endif
79 if (tmp == NULL) {
80 wwarning("malloc() failed. Retrying after 2s.");
81 sleep(2);
82 #ifdef TEST_WITH_GC
83 tmp = GC_malloc(size);
84 #else
85 tmp = malloc(size);
86 #endif
87 if (tmp == NULL) {
88 if (Aborting) {
89 fputs("Really Bad Error: recursive malloc() failure.", stderr);
90 exit(-1);
91 } else {
92 wfatal("virtual memory exhausted");
93 Aborting = 1;
94 wAbort(False);
98 return tmp;
101 void *wrealloc(void *ptr, size_t newsize)
103 void *nptr;
105 if (!ptr) {
106 nptr = wmalloc(newsize);
107 } else if (newsize == 0) {
108 wfree(ptr);
109 nptr = NULL;
110 } else {
111 #ifdef TEST_WITH_GC
112 nptr = GC_realloc(ptr, newsize);
113 #else
114 nptr = realloc(ptr, newsize);
115 #endif
116 if (nptr == NULL) {
117 wwarning("realloc() failed. Retrying after 2s.");
118 sleep(2);
119 #ifdef TEST_WITH_GC
120 nptr = GC_realloc(ptr, newsize);
121 #else
122 nptr = realloc(ptr, newsize);
123 #endif
124 if (nptr == NULL) {
125 if (Aborting) {
126 fputs("Really Bad Error: recursive realloc() failure.", stderr);
127 exit(-1);
128 } else {
129 wfatal("virtual memory exhausted");
130 Aborting = 1;
131 wAbort(False);
136 return nptr;
139 void *wretain(void *ptr)
141 int *refcount;
143 if (!table) {
144 table = WMCreateHashTable(WMIntHashCallbacks);
147 refcount = WMHashGet(table, ptr);
148 if (!refcount) {
149 refcount = wmalloc(sizeof(int));
150 *refcount = 1;
151 WMHashInsert(table, ptr, refcount);
152 #ifdef VERBOSE
153 printf("== %i (%p)\n", *refcount, ptr);
154 #endif
155 } else {
156 (*refcount)++;
157 #ifdef VERBOSE
158 printf("+ %i (%p)\n", *refcount, ptr);
159 #endif
162 return ptr;
165 void wfree(void *ptr)
167 #ifdef TEST_WITH_GC
168 GC_free(ptr);
169 #else
170 free(ptr);
171 #endif
174 void wrelease(void *ptr)
176 int *refcount;
178 refcount = WMHashGet(table, ptr);
179 if (!refcount) {
180 wwarning("trying to release unexisting data %p", ptr);
181 } else {
182 (*refcount)--;
183 if (*refcount < 1) {
184 #ifdef VERBOSE
185 printf("RELEASING %p\n", ptr);
186 #endif
187 WMHashRemove(table, ptr);
188 wfree(refcount);
189 wfree(ptr);
191 #ifdef VERBOSE
192 else {
193 printf("- %i (%p)\n", *refcount, ptr);
195 #endif