]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/cbdata.cc
3 * $Id: cbdata.cc,v 1.16 1998/02/20 21:04: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
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
;
85 cbdata_cmp(const void *p1
, const void *p2
)
87 return (char *) p1
- (char *) p2
;
91 cbdata_hash(const void *p
, unsigned int mod
)
93 return ((unsigned long) p
>> 8) % mod
;
100 debug(45, 3) ("cbdataInit\n");
101 htable
= hash_create(cbdata_cmp
, 1 << 8, cbdata_hash
);
102 cachemgrRegister("cbdata",
103 "Callback Data Registry Contents",
109 cbdataAddDbg(const void *p
, mem_type mem_type
, const char *file
, int line
)
111 cbdataAdd(const void *p
, mem_type mem_type
)
116 debug(45, 3) ("cbdataAdd: %p\n", p
);
117 assert(htable
!= NULL
);
118 assert(hash_lookup(htable
, p
) == NULL
);
119 c
= xcalloc(1, sizeof(cbdata
));
122 c
->mem_type
= mem_type
;
127 hash_join(htable
, (hash_link
*) c
);
134 cbdata
*c
= (cbdata
*) hash_lookup(htable
, p
);
137 debug(45, 3) ("cbdataFree: %p\n", p
);
141 debug(45, 3) ("cbdataFree: %p has %d locks, not freeing\n",
145 hash_remove_link(htable
, (hash_link
*) c
);
147 mem_type
= c
->mem_type
;
149 debug(45, 3) ("cbdataFree: freeing %p\n", p
);
150 if (mem_type
== MEM_NONE
)
153 memFree(mem_type
, p
);
157 cbdataLock(const void *p
)
162 c
= (cbdata
*) hash_lookup(htable
, p
);
163 debug(45, 3) ("cbdataLock: %p\n", p
);
169 cbdataUnlock(const void *p
)
174 c
= (cbdata
*) hash_lookup(htable
, p
);
175 debug(45, 3) ("cbdataUnlock: %p\n", p
);
177 assert(c
->locks
> 0);
179 if (c
->valid
|| c
->locks
)
181 hash_remove_link(htable
, (hash_link
*) c
);
184 debug(45, 3) ("cbdataUnlock: Freeing %p\n", p
);
189 cbdataValid(const void *p
)
194 c
= (cbdata
*) hash_lookup(htable
, p
);
195 debug(45, 3) ("cbdataValid: %p\n", p
);
197 assert(c
->locks
> 0);
203 cbdataDump(StoreEntry
* sentry
)
207 storeAppendPrintf(sentry
, "%d cbdata entries\n", cbdataCount
);
208 for (hptr
= hash_first(htable
); hptr
; hptr
= hash_next(htable
)) {
211 storeAppendPrintf(sentry
, "%20p %10s %d locks %s:%d\n",
213 c
->valid
? "VALID" : "NOT VALID",
217 storeAppendPrintf(sentry
, "%20p %10s %d locks\n",
219 c
->valid
? "VALID" : "NOT VALID",