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