]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/cbdata.cc
3 * $Id: cbdata.cc,v 1.18 1998/03/30 22:58:51 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
14 * the National Science Foundation.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 * These routines manage a set of registered callback data pointers.
34 * One of the easiest ways to make Squid coredump is to issue a
35 * callback to for some data structure which has previously been
36 * freed. With these routines, we register (add) callback data
37 * pointers, lock them just before registering the callback function,
38 * validate them before issuing the callback, and then free them
41 * In terms of time, the sequence goes something like this:
43 * foo = xcalloc(sizeof(foo));
47 * some_blocking_operation(..., callback_func, foo);
49 * some_blocking_operation_completes()
50 * if (cbdataValid(foo))
51 * callback_func(..., foo)
56 * The nice thing is that, we do not need to require that Unlock
57 * occurs before Free. If the Free happens first, then the
58 * callback data is marked invalid and the callback will never
59 * be made. When we Unlock and the lock count reaches zero,
60 * we free the memory if it is marked invalid.
65 static hash_table
*htable
= NULL
;
67 static int cbdataCount
= 0;
69 typedef struct _cbdata
{
81 static HASHCMP cbdata_cmp
;
82 static HASHHASH cbdata_hash
;
83 static void cbdataReallyFree(cbdata
*c
);
86 cbdata_cmp(const void *p1
, const void *p2
)
88 return (char *) p1
- (char *) p2
;
92 cbdata_hash(const void *p
, unsigned int mod
)
94 return ((unsigned long) p
>> 8) % mod
;
101 debug(45, 3) ("cbdataInit\n");
102 htable
= hash_create(cbdata_cmp
, 1 << 8, cbdata_hash
);
103 cachemgrRegister("cbdata",
104 "Callback Data Registry Contents",
110 cbdataAddDbg(const void *p
, mem_type mem_type
, const char *file
, int line
)
112 cbdataAdd(const void *p
, mem_type mem_type
)
117 debug(45, 3) ("cbdataAdd: %p\n", p
);
118 assert(htable
!= NULL
);
119 assert(hash_lookup(htable
, p
) == NULL
);
120 c
= xcalloc(1, sizeof(cbdata
));
123 c
->mem_type
= mem_type
;
128 hash_join(htable
, (hash_link
*) c
);
133 cbdataReallyFree(cbdata
*c
)
135 mem_type mem_type
= c
->mem_type
;
136 void *p
= (void *) c
->key
;
137 hash_remove_link(htable
, (hash_link
*) c
);
140 debug(45, 3) ("cbdataReallyFree: Freeing %p\n", p
);
141 if (mem_type
== MEM_NONE
)
144 memFree(mem_type
, p
);
150 cbdata
*c
= (cbdata
*) hash_lookup(htable
, p
);
152 debug(45, 3) ("cbdataFree: %p\n", p
);
156 debug(45, 3) ("cbdataFree: %p has %d locks, not freeing\n",
164 cbdataLock(const void *p
)
169 c
= (cbdata
*) hash_lookup(htable
, p
);
170 debug(45, 3) ("cbdataLock: %p\n", p
);
176 cbdataUnlock(const void *p
)
181 c
= (cbdata
*) hash_lookup(htable
, p
);
182 debug(45, 3) ("cbdataUnlock: %p\n", p
);
184 assert(c
->locks
> 0);
186 if (c
->valid
|| c
->locks
)
192 cbdataValid(const void *p
)
195 /* Maybe NULL should be considered valid? */
198 c
= (cbdata
*) hash_lookup(htable
, p
);
199 debug(45, 3) ("cbdataValid: %p\n", p
);
201 assert(c
->locks
> 0);
207 cbdataDump(StoreEntry
* sentry
)
211 storeAppendPrintf(sentry
, "%d cbdata entries\n", cbdataCount
);
212 for (hptr
= hash_first(htable
); hptr
; hptr
= hash_next(htable
)) {
215 storeAppendPrintf(sentry
, "%20p %10s %d locks %s:%d\n",
217 c
->valid
? "VALID" : "NOT VALID",
221 storeAppendPrintf(sentry
, "%20p %10s %d locks\n",
223 c
->valid
? "VALID" : "NOT VALID",