This patch is generated from the refcount branch of HEAD in squid Sun Jan 25 14:39:55 2004 GMT See http://devel.squid-cache.org/ Index: squid/configure.in diff -u squid/configure.in:1.25 squid/configure.in:1.21.2.1 --- squid/configure.in:1.25 Sat Sep 1 04:47:47 2001 +++ squid/configure.in Sat Sep 1 16:41:40 2001 @@ -9,7 +9,7 @@ dnl AC_INIT(src/main.c) AC_CONFIG_AUX_DIR(cfgaux) -AM_INIT_AUTOMAKE(Squid, 2.5-DEVEL) +AM_INIT_AUTOMAKE(Squid, 2.5-DEVEL-refcount) AM_CONFIG_HEADER(include/autoconf.h) AC_REVISION($Revision: 1.1 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) Index: squid/src/defines.h diff -u squid/src/defines.h:1.13 squid/src/defines.h:1.12.2.2 --- squid/src/defines.h:1.13 Thu Aug 16 00:39:03 2001 +++ squid/src/defines.h Sat Sep 1 16:41:41 2001 @@ -286,6 +286,13 @@ #define CBDATA_INIT_TYPE(type) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataAddType(CBDATA_##type, #type, sizeof(type), NULL))) #define CBDATA_INIT_TYPE_FREECB(type, free_func) (CBDATA_##type ? 0 : (CBDATA_##type = cbdataAddType(CBDATA_##type, #type, sizeof(type), free_func))) +/* rcdata macros */ +#define rcdataAlloc(type) ((type *)rcdataInternalAlloc(RCDATA_##type)) +#define RCDATA_TYPE(type) static rcdata_type RCDATA_##type = 0 +#define RCDATA_GLOBAL_TYPE(type) rcdata_type RCDATA_##type +#define RCDATA_INIT_TYPE(type) (RCDATA_##type ? 0 : (RCDATA_##type = rcdataAddType(RCDATA_##type, #type, sizeof(type), NULL))) +#define RCDATA_INIT_TYPE_FREECB(type, free_func) (RCDATA_##type ? 0 : (RCDATA_##type = rcdataAddType(RCDATA_##type, #type, sizeof(type), free_func))) + #ifndef O_TEXT #define O_TEXT 0 #endif Index: squid/src/enums.h diff -u squid/src/enums.h:1.22 squid/src/enums.h:1.21.6.2 --- squid/src/enums.h:1.22 Sun Aug 12 08:20:28 2001 +++ squid/src/enums.h Sat Sep 1 16:41:41 2001 @@ -716,6 +716,17 @@ } cbdata_type; /* + * rcdata types. similar to the cbdata type above, but managed + * in rcdata.c. This list is only a list of predefined types. Other types + * are added at runtime. + */ +typedef enum { + RCDATA_UNKNOWN = 0, + RCDATA_UNDEF = 0, + RCDATA_FIRST_CUSTOM_TYPE = 1000 +} rcdata_type; + +/* * Return codes from checkVary(request) */ enum { Index: squid/src/main.c diff -u squid/src/main.c:1.25 squid/src/main.c:1.23.2.2 --- squid/src/main.c:1.25 Thu Aug 16 00:39:03 2001 +++ squid/src/main.c Sat Sep 1 16:41:41 2001 @@ -629,6 +629,7 @@ #endif memInit(); cbdataInit(); + rcdataInit(); eventInit(); /* eventInit() is required for config parsing */ storeFsInit(); /* required for config parsing */ authenticateSchemeInit(); /* required for config parsign */ Index: squid/src/protos.h diff -u squid/src/protos.h:1.33 squid/src/protos.h:1.27.2.2 --- squid/src/protos.h:1.33 Thu Aug 30 09:24:13 2001 +++ squid/src/protos.h Sat Sep 1 16:41:41 2001 @@ -117,6 +117,27 @@ extern cbdata_type cbdataAddType(cbdata_type type, char *label, int size, FREE * free_func); extern int cbdataLocked(const void *p); +/* + * rcdata.c + */ +extern void rcdataInit(void); +#if RCDATA_DEBUG +extern void *rcdataInternalAllocDbg(rcdata_type type, int, const char *); +extern void rcdataReferenceDbg(const void *p, const char *, int); +extern void rcdataDereferenceDbg(const void *p, const char *, int); +#else +extern void *rcdataInternalAlloc(rcdata_type type); +extern void rcdataReference(const void *p); +extern void rcdataDereference(const void *p); +#endif +/* Note: Allocations is done using the rcdataAlloc macro */ +extern int rcdataValid(const void *p); +extern void rcdataInitType(rcdata_type type, char *label, int size, FREE * free_func); +extern rcdata_type rcdataAddType(rcdata_type type, char *label, int size, FREE * free_func); +extern int rcdataReferenced(const void *p); + + + extern void clientdbInit(void); extern void clientdbUpdate(struct in_addr, log_type, protocol_t, size_t); extern int clientdbCutoffDenied(struct in_addr); Index: squid/src/rcdata.c diff -u /dev/null squid/src/rcdata.c:1.1.4.1 --- /dev/null Sun Jan 25 06:39:27 2004 +++ squid/src/rcdata.c Mon May 14 05:54:08 2001 @@ -0,0 +1,250 @@ + +/* + * $Id: squid-refcount-HEAD,v 1.1 2004/08/17 20:55:13 hno Exp $ + * + * DEBUG: section 45 Reference-Counted Data Registry + * ORIGINAL AUTHOR: Duane Wessels + * Modified by Moez Mahfoudh (08/12/2000) + * Modified by Robert Collins (13/5/2001) to be refcounted + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +/* + * These routines manage a set of registered ref-counted data pointers. + * With these routines, we register (add) ref-counted data pointers + * (the first reference is automatic), and then reference and dereference + * them. Free automatically occurs on zero references. A ref-counted data + * pointer is valid when the refcount is positive. + * + * In terms of time, the sequence goes something like this: + * + * foo = rcdataAlloc(sizeof(foo),NULL); + * ... + * rcdataReference(foo); + * rcdataDereference(foo); + * rcdataDereference(foo);<-- free is triggered here. + * + */ + +#include "squid.h" + +static int rcdataCount = 0; + +typedef struct _rcdata { + int references; + int type; +#if RCDATA_DEBUG + const char *file; + int line; +#endif + void *y; /* cookie used while debugging */ + union { + void *pointer; + double double_float; + int integer; + } data; +} rcdata; + +static OBJH rcdataDump; + +struct { + MemPool *pool; + FREE *free_func; +} *rcdata_index = NULL; +int rcdata_types = 1; + +#define OFFSET_OF(type, member) ((int)(char *)&((type *)0L)->member) + +void +rcdataInitType(rcdata_type type, char *name, int size, FREE * free_func) +{ + char *label; + if (type >= rcdata_types) { + rcdata_index = xrealloc(rcdata_index, (type + 1) * sizeof(*rcdata_index)); + memset(&rcdata_index[rcdata_types], 0, + (type + 1 - rcdata_types) * sizeof(*rcdata_index)); + rcdata_types = type + 1; + } + if (rcdata_index[type].pool) + return; + label = xmalloc(strlen(name) + 20); + snprintf(label, strlen(name) + 20, "rcdata %s (%d)", name, (int) type); + assert(OFFSET_OF(rcdata, data) == (sizeof(rcdata) - sizeof(((rcdata *) NULL)->data))); + rcdata_index[type].pool = memPoolCreate(label, size + OFFSET_OF(rcdata, data)); + rcdata_index[type].free_func = free_func; +} + +rcdata_type +rcdataAddType(rcdata_type type, char *name, int size, FREE * free_func) +{ + if (type) + return type; + type = rcdata_types; + rcdataInitType(type, name, size, free_func); + return type; +} + +void +rcdataInit(void) +{ + debug(45, 3) ("rcdataInit\n"); + cachemgrRegister("rcdata", + "Callback Data Registry Contents", + rcdataDump, 0, 1); +#define CREATE_RCDATA(type) rcdataInitType(RCDATA_##type, #type, sizeof(type), NULL) +#define CREATE_RCDATA_FREE(type, free_func) rcdataInitType(RCDATA_##type, #type, sizeof(type), free_func) +} + +void * +#if RCDATA_DEBUG +rcdataInternalAllocDbg(rcdata_type type, const char *file, int line) +#else +rcdataInternalAlloc(rcdata_type type) +#endif +{ + rcdata *p; + assert(type > 0 && type < rcdata_types); + p = memPoolAlloc(rcdata_index[type].pool); + p->type = type; + p->references = 1; +#if RCDATA_DEBUG + p->file = file; + p->line = line; +#endif + p->y = p; + rcdataCount++; + + return (void *) &p->data; +} + +void * +rcdataInternalFree(void *p) +{ + rcdata *c; + FREE *free_func; + debug(45, 3) ("rcdataFree: %p\n", p); + c = (rcdata *) (((char *) p) - OFFSET_OF(rcdata, data)); + assert(c->y == c); + if (c->references) { + debug(45, 3) ("rcdataFree: %p has %d references, not freeing\n", + p, c->references); + return NULL; + } + rcdataCount--; + debug(45, 3) ("rcdataFree: Freeing %p\n", p); + free_func = rcdata_index[c->type].free_func; + if (free_func) + free_func((void *) p); + memPoolFree(rcdata_index[c->type].pool, c); + return NULL; +} + +int +rcdataReferenced(const void *p) +{ + rcdata *c; + assert(p); + c = (rcdata *) (((char *) p) - OFFSET_OF(rcdata, data)); + assert(c->y == c); + debug(45, 3) ("rcdataReferenced: %p = %d\n", p, c->references); + assert(c != NULL); + return c->references; +} + +void +#if RCDATA_DEBUG +rcdataReferenceDbg(const void *p, const char *file, int line) +#else +rcdataReference(const void *p) +#endif +{ + rcdata *c; + if (p == NULL) + return; + c = (rcdata *) (((char *) p) - OFFSET_OF(rcdata, data)); + assert(c->y == c); + debug(45, 3) ("rcdataReference: %p\n", p); + assert(c != NULL); + c->references++; +#if RCDATA_DEBUG + c->file = file; + c->line = line; +#endif +} + +void +#if RCDATA_DEBUG +rcdataDereferenceDbg(const void *p, const char *file, int line) +#else +rcdataDereference(const void *p) +#endif +{ + rcdata *c; + FREE *free_func; + if (p == NULL) + return; + c = (rcdata *) (((char *) p) - OFFSET_OF(rcdata, data)); + assert(c->y == c); + debug(45, 3) ("rcdataDereference: %p\n", p); + assert(c != NULL); + assert(c->references > 0); + c->references--; +#if RCDATA_DEBUG + c->file = file; + c->line = line; +#endif + if (c->references) + return; + rcdataCount--; + debug(45, 3) ("rcdataDereference: Freeing %p\n", p); + free_func = rcdata_index[c->type].free_func; + if (free_func) + free_func((void *) p); + memPoolFree(rcdata_index[c->type].pool, c); +} + +int +rcdataValid(const void *p) +{ + rcdata *c; + if (p == NULL) + return 1; /* A NULL pointer cannot become invalid */ + debug(45, 3) ("rcdataValid: %p\n", p); + c = (rcdata *) (((char *) p) - OFFSET_OF(rcdata, data)); + assert(c->y == c); + assert(c->references > 0); + return c->references; +} + +static void +rcdataDump(StoreEntry * sentry) +{ + storeAppendPrintf(sentry, "%d rcdata entries\n", rcdataCount); + storeAppendPrintf(sentry, "see also memory pools section\n"); +} squid-refcount-HEAD.new squid-refcount-HEAD differ: char 68, line 2