]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/cbdata.cc
3 * $Id: cbdata.cc,v 1.24 1998/07/22 20:37:05 wessels Exp $
5 * DEBUG: section 45 Callback Data Registry
6 * AUTHOR: Duane Wessels
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37 * These routines manage a set of registered callback data pointers.
38 * One of the easiest ways to make Squid coredump is to issue a
39 * callback to for some data structure which has previously been
40 * freed. With these routines, we register (add) callback data
41 * pointers, lock them just before registering the callback function,
42 * validate them before issuing the callback, and then free them
45 * In terms of time, the sequence goes something like this:
47 * foo = xcalloc(sizeof(foo));
51 * some_blocking_operation(..., callback_func, foo);
53 * some_blocking_operation_completes()
54 * if (cbdataValid(foo))
55 * callback_func(..., foo)
60 * The nice thing is that, we do not need to require that Unlock
61 * occurs before Free. If the Free happens first, then the
62 * callback data is marked invalid and the callback will never
63 * be made. When we Unlock and the lock count reaches zero,
64 * we free the memory if it is marked invalid.
69 static hash_table
*htable
= NULL
;
71 static int cbdataCount
= 0;
73 typedef struct _cbdata
{
85 static HASHCMP cbdata_cmp
;
86 static HASHHASH cbdata_hash
;
87 static void cbdataReallyFree(cbdata
* c
);
90 cbdata_cmp(const void *p1
, const void *p2
)
92 return (char *) p1
- (char *) p2
;
96 cbdata_hash(const void *p
, unsigned int mod
)
98 return ((unsigned long) p
>> 8) % mod
;
105 debug(45, 3) ("cbdataInit\n");
106 htable
= hash_create(cbdata_cmp
, 1 << 8, cbdata_hash
);
107 cachemgrRegister("cbdata",
108 "Callback Data Registry Contents",
114 cbdataAddDbg(const void *p
, mem_type mem_type
, const char *file
, int line
)
116 cbdataAdd(const void *p
, mem_type mem_type
)
121 debug(45, 3) ("cbdataAdd: %p\n", p
);
122 assert(htable
!= NULL
);
123 assert(hash_lookup(htable
, p
) == NULL
);
124 c
= xcalloc(1, sizeof(cbdata
));
127 c
->mem_type
= mem_type
;
132 hash_join(htable
, (hash_link
*) c
);
137 cbdataReallyFree(cbdata
* c
)
139 mem_type mem_type
= c
->mem_type
;
140 void *p
= (void *) c
->key
;
141 hash_remove_link(htable
, (hash_link
*) c
);
144 if (mem_type
== MEM_DONTFREE
)
146 debug(45, 3) ("cbdataReallyFree: Freeing %p\n", p
);
147 if (mem_type
== MEM_NONE
)
150 memFree(mem_type
, p
);
156 cbdata
*c
= (cbdata
*) hash_lookup(htable
, p
);
158 debug(45, 3) ("cbdataFree: %p\n", p
);
162 debug(45, 3) ("cbdataFree: %p has %d locks, not freeing\n",
170 cbdataLock(const void *p
)
175 c
= (cbdata
*) hash_lookup(htable
, p
);
176 debug(45, 3) ("cbdataLock: %p\n", p
);
182 cbdataUnlock(const void *p
)
187 c
= (cbdata
*) hash_lookup(htable
, p
);
188 debug(45, 3) ("cbdataUnlock: %p\n", p
);
190 assert(c
->locks
> 0);
192 if (c
->valid
|| c
->locks
)
198 cbdataValid(const void *p
)
201 /* Maybe NULL should be considered valid? */
204 c
= (cbdata
*) hash_lookup(htable
, p
);
205 debug(45, 3) ("cbdataValid: %p\n", p
);
207 assert(c
->locks
> 0);
213 cbdataDump(StoreEntry
* sentry
)
217 storeAppendPrintf(sentry
, "%d cbdata entries\n", cbdataCount
);
219 while ((hptr
= hash_next(htable
))) {
222 storeAppendPrintf(sentry
, "%20p %10s %d locks %s:%d\n",
224 c
->valid
? "VALID" : "NOT VALID",
228 storeAppendPrintf(sentry
, "%20p %10s %d locks\n",
230 c
->valid
? "VALID" : "NOT VALID",