Mac OS X-style window cycling.
[wmaker-crm.git] / WINGs / memory.c
blob410de379451a90406daef7b22d79dfa5028f220d
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 *wmalloc0(size_t size)
103 void *ptr = wmalloc(size);
104 if (!ptr)
105 return NULL;
107 memset(ptr, 0, size);
109 return ptr;
112 void *wrealloc(void *ptr, size_t newsize)
114 void *nptr;
116 if (!ptr) {
117 nptr = wmalloc(newsize);
118 } else if (newsize == 0) {
119 wfree(ptr);
120 nptr = NULL;
121 } else {
122 #ifdef TEST_WITH_GC
123 nptr = GC_realloc(ptr, newsize);
124 #else
125 nptr = realloc(ptr, newsize);
126 #endif
127 if (nptr == NULL) {
128 wwarning("realloc() failed. Retrying after 2s.");
129 sleep(2);
130 #ifdef TEST_WITH_GC
131 nptr = GC_realloc(ptr, newsize);
132 #else
133 nptr = realloc(ptr, newsize);
134 #endif
135 if (nptr == NULL) {
136 if (Aborting) {
137 fputs("Really Bad Error: recursive realloc() failure.", stderr);
138 exit(-1);
139 } else {
140 wfatal("virtual memory exhausted");
141 Aborting = 1;
142 wAbort(False);
147 return nptr;
150 void *wretain(void *ptr)
152 int *refcount;
154 if (!table) {
155 table = WMCreateHashTable(WMIntHashCallbacks);
158 refcount = WMHashGet(table, ptr);
159 if (!refcount) {
160 refcount = wmalloc(sizeof(int));
161 *refcount = 1;
162 WMHashInsert(table, ptr, refcount);
163 #ifdef VERBOSE
164 printf("== %i (%p)\n", *refcount, ptr);
165 #endif
166 } else {
167 (*refcount)++;
168 #ifdef VERBOSE
169 printf("+ %i (%p)\n", *refcount, ptr);
170 #endif
173 return ptr;
176 void wfree(void *ptr)
178 #ifdef TEST_WITH_GC
179 GC_free(ptr);
180 #else
181 free(ptr);
182 #endif
185 void wrelease(void *ptr)
187 int *refcount;
189 refcount = WMHashGet(table, ptr);
190 if (!refcount) {
191 wwarning("trying to release unexisting data %p", ptr);
192 } else {
193 (*refcount)--;
194 if (*refcount < 1) {
195 #ifdef VERBOSE
196 printf("RELEASING %p\n", ptr);
197 #endif
198 WMHashRemove(table, ptr);
199 wfree(refcount);
200 wfree(ptr);
202 #ifdef VERBOSE
203 else {
204 printf("- %i (%p)\n", *refcount, ptr);
206 #endif