---------------------
PatchSet 275 
Date: 2000/05/08 18:02:07
Author: hno
Branch: hno-devel
Tag: (none) 
Log:
syncronized with "modio"

Members: 
	configure.in:1.1.1.3.6.7.2.5->1.1.1.3.6.7.2.6 
	src/asn.c:1.1.1.3.6.1->1.1.1.3.6.1.2.1 
	src/cf.data.pre:1.1.1.3.10.6.2.3->1.1.1.3.10.6.2.4 
	src/client_side.c:1.1.1.3.10.7.2.3->1.1.1.3.10.7.2.4 
	src/delay_pools.c:1.1.1.3.10.3->1.1.1.3.10.3.2.1 
	src/net_db.c:1.1.1.3.10.2->1.1.1.3.10.2.2.1 
	src/peer_digest.c:1.1.1.3.6.1->1.1.1.3.6.1.2.1 
	src/protos.h:1.1.1.3.10.8.2.3->1.1.1.3.10.8.2.4 
	src/pump.c:1.1.1.3.10.2.2.1->1.1.1.3.10.2.2.2 
	src/stat.c:1.1.1.3.10.4->1.1.1.3.10.4.2.1 
	src/store.c:1.1.1.3.10.8.2.2->1.1.1.3.10.8.2.3 
	src/store_client.c:1.1.1.3.10.4.2.1->1.1.1.3.10.4.2.2 
	src/store_digest.c:1.1.1.3.6.1->1.1.1.3.6.1.2.1 
	src/store_swapout.c:1.1.1.3.10.5->1.1.1.3.10.5.2.1 
	src/structs.h:1.1.1.3.10.8.2.4->1.1.1.3.10.8.2.5 
	src/urn.c:1.1.1.3.6.1->1.1.1.3.6.1.2.1 

Index: squid/configure.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/configure.in,v
retrieving revision 1.1.1.3.6.7.2.5
retrieving revision 1.1.1.3.6.7.2.6
diff -u -r1.1.1.3.6.7.2.5 -r1.1.1.3.6.7.2.6
--- squid/configure.in	2 May 2000 23:21:53 -0000	1.1.1.3.6.7.2.5
+++ squid/configure.in	8 May 2000 18:02:07 -0000	1.1.1.3.6.7.2.6
@@ -3,13 +3,13 @@
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.1.1.3.6.7.2.5 2000/05/02 23:21:53 hno Exp $
+dnl  $Id: configure.in,v 1.1.1.3.6.7.2.6 2000/05/08 18:02:07 hno Exp $
 dnl
 dnl
 dnl
 AC_INIT(src/main.c)
 AC_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.1.1.3.6.7.2.5 $)dnl
+AC_REVISION($Revision: 1.1.1.3.6.7.2.6 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AC_CONFIG_AUX_DIR(cfgaux)
 
@@ -315,7 +315,7 @@
     STORE_MODULES="ufs"
   fi
 ])
-echo "Store moules built: $STORE_MODULES"
+echo "Store modules built: $STORE_MODULES"
 AC_SUBST(STORE_MODULES)
 STORE_OBJS="fs/`echo $STORE_MODULES|sed -e's% %.a fs/%g'`.a"
 AC_SUBST(STORE_OBJS)
Index: squid/src/asn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/asn.c,v
retrieving revision 1.1.1.3.6.1
retrieving revision 1.1.1.3.6.1.2.1
diff -u -r1.1.1.3.6.1 -r1.1.1.3.6.1.2.1
--- squid/src/asn.c	20 Apr 2000 18:14:21 -0000	1.1.1.3.6.1
+++ squid/src/asn.c	8 May 2000 18:02:07 -0000	1.1.1.3.6.1.2.1
@@ -1,5 +1,5 @@
 /*
- * $Id: asn.c,v 1.1.1.3.6.1 2000/04/20 18:14:21 hno Exp $
+ * $Id: asn.c,v 1.1.1.3.6.1.2.1 2000/05/08 18:02:07 hno Exp $
  *
  * DEBUG: section 53    AS Number handling
  * AUTHOR: Duane Wessels, Kostas Anagnostakis
@@ -62,6 +62,7 @@
 
 struct _ASState {
     StoreEntry *entry;
+    store_client *sc;
     request_t *request;
     int as_number;
     off_t seen;
@@ -195,16 +196,17 @@
     asState->request = requestLink(req);
     if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) {
 	e = storeCreateEntry(asres, asres, null_request_flags, METHOD_GET);
-	storeClientListAdd(e, asState);
+	asState->sc = storeClientListAdd(e, asState);
 	fwdStart(-1, e, asState->request);
     } else {
 	storeLockObject(e);
-	storeClientListAdd(e, asState);
+	asState->sc = storeClientListAdd(e, asState);
     }
     asState->entry = e;
     asState->seen = 0;
     asState->offset = 0;
-    storeClientCopy(e,
+    storeClientCopy(asState->sc,
+        e,
 	asState->seen,
 	asState->offset,
 	4096,
@@ -259,7 +261,8 @@
 	asState->seen, asState->offset);
     if (e->store_status == STORE_PENDING) {
 	debug(53, 3) ("asHandleReply: store_status == STORE_PENDING: %s\n", storeUrl(e));
-	storeClientCopy(e,
+	storeClientCopy(asState->sc,
+            e,
 	    asState->seen,
 	    asState->offset,
 	    SM_PAGE_SIZE,
@@ -268,7 +271,8 @@
 	    asState);
     } else if (asState->seen < e->mem_obj->inmem_hi) {
 	debug(53, 3) ("asHandleReply: asState->seen < e->mem_obj->inmem_hi %s\n", storeUrl(e));
-	storeClientCopy(e,
+	storeClientCopy(asState->sc,
+            e,
 	    asState->seen,
 	    asState->offset,
 	    SM_PAGE_SIZE,
@@ -287,7 +291,7 @@
 {
     ASState *asState = data;
     debug(53, 3) ("asnStateFree: %s\n", storeUrl(asState->entry));
-    storeUnregister(asState->entry, asState);
+    storeUnregister(asState->sc, asState->entry, asState);
     storeUnlockObject(asState->entry);
     requestUnlink(asState->request);
     cbdataFree(asState);
Index: squid/src/cf.data.pre
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v
retrieving revision 1.1.1.3.10.6.2.3
retrieving revision 1.1.1.3.10.6.2.4
diff -u -r1.1.1.3.10.6.2.3 -r1.1.1.3.10.6.2.4
--- squid/src/cf.data.pre	2 May 2000 23:21:53 -0000	1.1.1.3.10.6.2.3
+++ squid/src/cf.data.pre	8 May 2000 18:02:07 -0000	1.1.1.3.10.6.2.4
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.1.1.3.10.6.2.3 2000/05/02 23:21:53 hno Exp $
+# $Id: cf.data.pre,v 1.1.1.3.10.6.2.4 2000/05/08 18:02:07 hno Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
Index: squid/src/client_side.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v
retrieving revision 1.1.1.3.10.7.2.3
retrieving revision 1.1.1.3.10.7.2.4
diff -u -r1.1.1.3.10.7.2.3 -r1.1.1.3.10.7.2.4
--- squid/src/client_side.c	2 May 2000 23:21:53 -0000	1.1.1.3.10.7.2.3
+++ squid/src/client_side.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.7.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.c,v 1.1.1.3.10.7.2.3 2000/05/02 23:21:53 hno Exp $
+ * $Id: client_side.c,v 1.1.1.3.10.7.2.4 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -74,6 +74,7 @@
 /* Local functions */
 
 static CWCB clientWriteComplete;
+static CWCB clientWriteBodyComplete;
 static PF clientReadRequest;
 static PF connStateFree;
 static PF requestTimeout;
@@ -194,11 +195,11 @@
     if (h->request == NULL)
 	h->request = requestLink(requestCreate(m, PROTO_NONE, null_string));
     e = storeCreateEntry(h->uri, h->log_uri, flags, m);
-    storeClientListAdd(e, h);
+    h->sc = storeClientListAdd(e, h);
 #if DELAY_POOLS
-    delaySetStoreClient(e, h, delayClient(h->request));
+    delaySetStoreClient(h->sc, delayClient(h->request));
 #endif
-    storeClientCopy(e, 0, 0, CLIENT_SOCK_SZ,
+    storeClientCopy(h->sc, e, 0, 0, CLIENT_SOCK_SZ,
 	memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, h);
     return e;
 }
@@ -351,16 +352,18 @@
      * it is not, then the beginning of the object data might get
      * freed from memory before we need to access it.
      */
+#if STORE_CLIENT_LIST_SEARCH
     assert(storeClientListSearch(http->old_entry->mem_obj, http));
+#endif
     entry = storeCreateEntry(url,
 	http->log_uri,
 	http->request->flags,
 	http->request->method);
     /* NOTE, don't call storeLockObject(), storeCreateEntry() does it */
-    storeClientListAdd(entry, http);
+    http->sc = storeClientListAdd(entry, http);
 #if DELAY_POOLS
     /* delay_id is already set on original store client */
-    delaySetStoreClient(entry, http, delayClient(http->request));
+    delaySetStoreClient(http->sc, delayClient(http->request));
 #endif
     http->request->lastmod = http->old_entry->lastmod;
     debug(33, 5) ("clientProcessExpired: lastmod %d\n", (int) entry->lastmod);
@@ -370,7 +373,7 @@
     /* Register with storage manager to receive updates when data comes in. */
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n");
-    storeClientCopy(entry,
+    storeClientCopy(http->sc, entry,
 	http->out.offset,
 	http->out.offset,
 	CLIENT_SOCK_SZ,
@@ -444,7 +447,7 @@
 	/* We have an existing entry, but failed to validate it */
 	/* Its okay to send the old one anyway */
 	http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
-	storeUnregister(entry, http);
+	storeUnregister(http->sc, entry, http);
 	storeUnlockObject(entry);
 	entry = http->entry = http->old_entry;
     } else if (STORE_PENDING == entry->store_status && 0 == status) {
@@ -454,12 +457,12 @@
 	    debug(33, 3) ("clientHandleIMSReply: Reply is too large '%s', using old entry\n", url);
 	    /* use old entry, this repeats the code abovez */
 	    http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
-	    storeUnregister(entry, http);
+	    storeUnregister(http->sc, entry, http);
 	    storeUnlockObject(entry);
 	    entry = http->entry = http->old_entry;
 	    /* continue */
 	} else {
-	    storeClientCopy(entry,
+	    storeClientCopy(http->sc, entry,
 		http->out.offset + size,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -484,7 +487,7 @@
 	 * not the body they refer to.  */
 	httpReplyUpdateOnNotModified(oldentry->mem_obj->reply, mem->reply);
 	storeTimestampsSet(oldentry);
-	storeUnregister(entry, http);
+	storeUnregister(http->sc, entry, http);
 	storeUnlockObject(entry);
 	entry = http->entry = oldentry;
 	entry->timestamp = squid_curtime;
@@ -501,14 +504,14 @@
 	    storeTimestampsSet(http->old_entry);
 	    http->log_type = LOG_TCP_REFRESH_HIT;
 	}
-	storeUnregister(http->old_entry, http);
+	storeUnregister(http->sc, http->old_entry, http);
 	storeUnlockObject(http->old_entry);
 	recopy = 0;
     }
     http->old_entry = NULL;	/* done with old_entry */
     assert(!EBIT_TEST(entry->flags, ENTRY_ABORTED));
     if (recopy) {
-	storeClientCopy(entry,
+	storeClientCopy(http->sc, entry,
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -687,7 +690,7 @@
 	 */
 	if ((e = http->entry)) {
 	    http->entry = NULL;
-	    storeUnregister(e, http);
+	    storeUnregister(http->sc, e, http);
 	    storeUnlockObject(e);
 	}
 #endif
@@ -747,14 +750,14 @@
     stringClean(&http->range_iter.boundary);
     if ((e = http->entry)) {
 	http->entry = NULL;
-	storeUnregister(e, http);
+	storeUnregister(http->sc, e, http);
 	storeUnlockObject(e);
     }
     /* old_entry might still be set if we didn't yet get the reply
      * code in clientHandleIMSReply() */
     if ((e = http->old_entry)) {
 	http->old_entry = NULL;
-	storeUnregister(e, http);
+	storeUnregister(http->sc, e, http);
 	storeUnlockObject(e);
     }
     requestUnlink(http->request);
@@ -2024,7 +2027,7 @@
 	http->log_type = LOG_TCP_SWAPFAIL_MISS;
 	if ((e = http->entry)) {
 	    http->entry = NULL;
-	    storeUnregister(e, http);
+	    storeUnregister(http->sc, e, http);
 	    storeUnlockObject(e);
 	}
 	clientProcessMiss(http);
@@ -2046,7 +2049,7 @@
 	    clientProcessMiss(http);
 	} else {
 	    debug(33, 3) ("clientCacheHit: waiting for HTTP reply headers\n");
-	    storeClientCopy(e,
+	    storeClientCopy(http->sc, e,
 		http->out.offset + size,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -2132,7 +2135,7 @@
 	    MemBuf mb = httpPacked304Reply(e->mem_obj->reply);
 	    http->log_type = LOG_TCP_IMS_HIT;
 	    memFree(buf, MEM_CLIENT_SOCK_BUF);
-	    storeUnregister(e, http);
+	    storeUnregister(http->sc, e, http);
 	    storeUnlockObject(e);
 	    e = clientCreateStoreEntry(http, http->request->method, null_request_flags);
 	    http->entry = e;
@@ -2427,6 +2430,14 @@
 	memFree(buf, MEM_CLIENT_SOCK_BUF);
 	return;
     }
+    /* Shortcut if we're only sending a chunk of the body out */
+    if ((!http->request->range) && (http->out.offset != 0)) {
+        /* If we're only writing a body, just spray it out .. */
+        http->out.offset += body_size;
+        comm_write(fd, buf, size, clientWriteBodyComplete, http, NULL);
+            /* NULL because clientWriteBodyComplete frees it */
+        return;
+    }
     if (http->out.offset == 0) {
 	if (Config.onoff.log_mime_hdrs) {
 	    size_t k;
@@ -2440,7 +2451,7 @@
 	if (rep && clientReplyBodyTooLarge(rep->content_length)) {
 	    ErrorState *err = errorCon(ERR_TOO_BIG, HTTP_FORBIDDEN);
 	    err->request = requestLink(http->request);
-	    storeUnregister(http->entry, http);
+	    storeUnregister(http->sc, http->entry, http);
 	    storeUnlockObject(http->entry);
 	    http->entry = clientCreateStoreEntry(http, http->request->method,
 		null_request_flags);
@@ -2456,7 +2467,7 @@
 		body_size, rep->hdr_sz);
 	} else if (size < CLIENT_SOCK_SZ && entry->store_status == STORE_PENDING) {
 	    /* wait for more to arrive */
-	    storeClientCopy(entry,
+	    storeClientCopy(http->sc, entry,
 		http->out.offset + size,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -2567,10 +2578,10 @@
 	debug(33, 1) ("clientKeepaliveNextRequest: FD %d Sending next\n",
 	    conn->fd);
 	assert(entry);
-	if (0 == storeClientCopyPending(entry, http)) {
+	if (0 == storeClientCopyPending(http->sc, entry, http)) {
 	    if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 		debug(33, 0) ("clientKeepaliveNextRequest: ENTRY_ABORTED\n");
-	    storeClientCopy(entry,
+	    storeClientCopy(http->sc, entry,
 		http->out.offset,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -2582,6 +2593,14 @@
 }
 
 static void
+clientWriteBodyComplete(int fd, char *buf, size_t size, int errflag,
+void *data)
+{
+    memFree(buf, MEM_CLIENT_SOCK_BUF);
+    clientWriteComplete(fd, buf, size, errflag, data);
+}
+
+static void
 clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     clientHttpRequest *http = data;
@@ -2661,7 +2680,7 @@
 	http->oldte_rv = 0x00;
 	if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	    debug(33, 0) ("clientWriteComplete 2: ENTRY_ABORTED\n");
-	storeClientCopy(entry,
+	storeClientCopy(http->sc, entry,
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -2691,7 +2710,7 @@
     err->request = requestLink(r);
     err->src_addr = http->conn->peer.sin_addr;
     if (http->entry) {
-	storeUnregister(http->entry, http);
+	storeUnregister(http->sc, http->entry, http);
 	storeUnlockObject(http->entry);
     }
     http->entry = clientCreateStoreEntry(http, r->method, null_request_flags);
@@ -2819,11 +2838,11 @@
 	storeLockObject(http->entry);
 	storeCreateMemObject(http->entry, http->uri, http->log_uri);
 	http->entry->mem_obj->method = r->method;
-	storeClientListAdd(http->entry, http);
+	http->sc = storeClientListAdd(http->entry, http);
 #if DELAY_POOLS
-	delaySetStoreClient(http->entry, http, delayClient(r));
+	delaySetStoreClient(http->sc, delayClient(r));
 #endif
-	storeClientCopy(http->entry,
+	storeClientCopy(http->sc, http->entry,
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -2854,7 +2873,7 @@
     if (http->entry) {
 	if (EBIT_TEST(http->entry->flags, ENTRY_SPECIAL))
 	    debug(33, 0) ("clientProcessMiss: miss on a special object (%s).\n", url);
-	storeUnregister(http->entry, http);
+	storeUnregister(http->sc, http->entry, http);
 	storeUnlockObject(http->entry);
 	http->entry = NULL;
     }
Index: squid/src/delay_pools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/delay_pools.c,v
retrieving revision 1.1.1.3.10.3
retrieving revision 1.1.1.3.10.3.2.1
diff -u -r1.1.1.3.10.3 -r1.1.1.3.10.3.2.1
--- squid/src/delay_pools.c	21 Apr 2000 22:22:03 -0000	1.1.1.3.10.3
+++ squid/src/delay_pools.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.3.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: delay_pools.c,v 1.1.1.3.10.3 2000/04/21 22:22:03 hno Exp $
+ * $Id: delay_pools.c,v 1.1.1.3.10.3.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 77    Delay Pools
  * AUTHOR: David Luyer <luyer@ucs.uwa.edu.au>
@@ -609,7 +609,9 @@
     int i = 0;
     int found = 0;
     store_client *sc;
-    for (sc = mem->clients; sc; sc = sc->next) {
+    dlink_node *node;
+    for (node = mem->clients.head; node; node = node->next) {
+        sc = (store_client *)node->data;
 	if (sc->callback_data == NULL)	/* open slot */
 	    continue;
 	if (sc->type != STORE_MEM_CLIENT)
@@ -626,8 +628,10 @@
     int j;
     int jmax = -1;
     store_client *sc;
+    dlink_node *node;
     delay_id d = 0;
-    for (sc = mem->clients; sc; sc = sc->next) {
+    for (node = mem->clients.head; node; node = node->next) {
+        sc = (store_client *)node->data;
 	if (sc->callback_data == NULL)	/* open slot */
 	    continue;
 	if (sc->type != STORE_MEM_CLIENT)
@@ -642,9 +646,8 @@
 }
 
 void
-delaySetStoreClient(StoreEntry * e, void *data, delay_id delay_id)
+delaySetStoreClient(store_client *sc, delay_id delay_id)
 {
-    store_client *sc = storeClientListSearch(e->mem_obj, data);
     assert(sc != NULL);
     sc->delay_id = delay_id;
     delayRegisterDelayIdPtr(&sc->delay_id);
Index: squid/src/net_db.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/net_db.c,v
retrieving revision 1.1.1.3.10.2
retrieving revision 1.1.1.3.10.2.2.1
diff -u -r1.1.1.3.10.2 -r1.1.1.3.10.2.2.1
--- squid/src/net_db.c	20 Apr 2000 18:14:22 -0000	1.1.1.3.10.2
+++ squid/src/net_db.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.2.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: net_db.c,v 1.1.1.3.10.2 2000/04/20 18:14:22 hno Exp $
+ * $Id: net_db.c,v 1.1.1.3.10.2.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 38    Network Measurement Database
  * AUTHOR: Duane Wessels
@@ -40,6 +40,7 @@
 typedef struct {
     peer *p;
     StoreEntry *e;
+    store_client *sc;
     request_t *r;
     off_t seen;
     off_t used;
@@ -591,11 +592,11 @@
 	netdbExchangeDone(ex);
     } else if (ex->e->store_status == STORE_PENDING) {
 	debug(38, 3) ("netdbExchangeHandleReply: STORE_PENDING\n");
-	storeClientCopy(ex->e, ex->seen, ex->used, ex->buf_sz,
+	storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz,
 	    ex->buf, netdbExchangeHandleReply, ex);
     } else if (ex->seen < ex->e->mem_obj->inmem_hi) {
 	debug(38, 3) ("netdbExchangeHandleReply: ex->e->mem_obj->inmem_hi\n");
-	storeClientCopy(ex->e, ex->seen, ex->used, ex->buf_sz,
+	storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz,
 	    ex->buf, netdbExchangeHandleReply, ex);
     } else {
 	debug(38, 3) ("netdbExchangeHandleReply: Done\n");
@@ -610,7 +611,7 @@
     debug(38, 3) ("netdbExchangeDone: %s\n", storeUrl(ex->e));
     memFree(ex->buf, MEM_4K_BUF);
     requestUnlink(ex->r);
-    storeUnregister(ex->e, ex);
+    storeUnregister(ex->sc, ex->e, ex);
     storeUnlockObject(ex->e);
     cbdataUnlock(ex->p);
     cbdataFree(ex);
@@ -968,8 +969,8 @@
     ex->buf_sz = 4096;;
     ex->buf = memAllocate(MEM_4K_BUF);
     assert(NULL != ex->e);
-    storeClientListAdd(ex->e, ex);
-    storeClientCopy(ex->e, ex->seen, ex->used, ex->buf_sz,
+    ex->sc = storeClientListAdd(ex->e, ex);
+    storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz,
 	ex->buf, netdbExchangeHandleReply, ex);
     ex->r->flags.loopdetect = 1;	/* cheat! -- force direct */
     if (p->login)
Index: squid/src/peer_digest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/peer_digest.c,v
retrieving revision 1.1.1.3.6.1
retrieving revision 1.1.1.3.6.1.2.1
diff -u -r1.1.1.3.6.1 -r1.1.1.3.6.1.2.1
--- squid/src/peer_digest.c	20 Apr 2000 18:14:22 -0000	1.1.1.3.6.1
+++ squid/src/peer_digest.c	8 May 2000 18:02:08 -0000	1.1.1.3.6.1.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: peer_digest.c,v 1.1.1.3.6.1 2000/04/20 18:14:22 hno Exp $
+ * $Id: peer_digest.c,v 1.1.1.3.6.1.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 72    Peer Digest Routines
  * AUTHOR: Alex Rousskov
@@ -312,11 +312,11 @@
 	debug(72, 5) ("peerDigestRequest: found old entry\n");
 	storeLockObject(old_e);
 	storeCreateMemObject(old_e, url, url);
-	storeClientListAdd(old_e, fetch);
+	fetch->old_sc = storeClientListAdd(old_e, fetch);
     }
     e = fetch->entry = storeCreateEntry(url, url, req->flags, req->method);
     assert(EBIT_TEST(e->flags, KEY_PRIVATE));
-    storeClientListAdd(e, fetch);
+    fetch->sc = storeClientListAdd(e, fetch);
     /* set lastmod to trigger IMS request if possible */
     if (old_e)
 	e->lastmod = old_e->lastmod;
@@ -326,7 +326,7 @@
     fwdStart(-1, e, req);
     cbdataLock(fetch);
     cbdataLock(fetch->pd);
-    storeClientCopy(e, 0, 0, 4096, memAllocate(MEM_4K_BUF),
+    storeClientCopy(fetch->sc, e, 0, 0, 4096, memAllocate(MEM_4K_BUF),
 	peerDigestFetchReply, fetch);
 }
 
@@ -365,7 +365,7 @@
 	    httpReplyUpdateOnNotModified(fetch->old_entry->mem_obj->reply, reply);
 	    storeTimestampsSet(fetch->old_entry);
 	    /* get rid of 304 reply */
-	    storeUnregister(fetch->entry, fetch);
+	    storeUnregister(fetch->sc, fetch->entry, fetch);
 	    storeUnlockObject(fetch->entry);
 	    fetch->entry = fetch->old_entry;
 	    fetch->old_entry = NULL;
@@ -376,7 +376,7 @@
 	    /* get rid of old entry if any */
 	    if (fetch->old_entry) {
 		debug(72, 3) ("peerDigestFetchReply: got new digest, releasing old one\n");
-		storeUnregister(fetch->old_entry, fetch);
+		storeUnregister(fetch->old_sc, fetch->old_entry, fetch);
 		storeReleaseRequest(fetch->old_entry);
 		storeUnlockObject(fetch->old_entry);
 		fetch->old_entry = NULL;
@@ -391,14 +391,14 @@
 	if (status == HTTP_NOT_MODIFIED && fetch->pd->cd)
 	    peerDigestFetchStop(fetch, buf, "Not modified");
 	else
-	    storeClientCopy(fetch->entry,	/* have to swap in */
+	    storeClientCopy(fetch->sc, fetch->entry,	/* have to swap in */
 		0, 0, SM_PAGE_SIZE, buf, peerDigestSwapInHeaders, fetch);
     } else {
 	/* need more data, do we have space? */
 	if (size >= SM_PAGE_SIZE)
 	    peerDigestFetchAbort(fetch, buf, "reply header too big");
 	else
-	    storeClientCopy(fetch->entry, size, 0, SM_PAGE_SIZE, buf,
+	    storeClientCopy(fetch->sc, fetch->entry, size, 0, SM_PAGE_SIZE, buf,
 		peerDigestFetchReply, fetch);
     }
 }
@@ -425,7 +425,7 @@
 	    return;
 	}
 	fetch->offset += hdr_size;
-	storeClientCopy(fetch->entry, size, fetch->offset,
+	storeClientCopy(fetch->sc, fetch->entry, size, fetch->offset,
 	    SM_PAGE_SIZE, buf,
 	    peerDigestSwapInCBlock, fetch);
     } else {
@@ -433,7 +433,7 @@
 	if (size >= SM_PAGE_SIZE)
 	    peerDigestFetchAbort(fetch, buf, "stored header too big");
 	else
-	    storeClientCopy(fetch->entry, size, 0, SM_PAGE_SIZE, buf,
+	    storeClientCopy(fetch->sc, fetch->entry, size, 0, SM_PAGE_SIZE, buf,
 		peerDigestSwapInHeaders, fetch);
     }
 }
@@ -459,7 +459,7 @@
 	    memFree(buf, MEM_4K_BUF);
 	    buf = NULL;
 	    assert(pd->cd->mask);
-	    storeClientCopy(fetch->entry,
+	    storeClientCopy(fetch->sc, fetch->entry,
 		seen,
 		fetch->offset,
 		pd->cd->mask_size,
@@ -473,7 +473,7 @@
 	if (size >= SM_PAGE_SIZE)
 	    peerDigestFetchAbort(fetch, buf, "digest cblock too big");
 	else
-	    storeClientCopy(fetch->entry, size, 0, SM_PAGE_SIZE, buf,
+	    storeClientCopy(fetch->sc, fetch->entry, size, 0, SM_PAGE_SIZE, buf,
 		peerDigestSwapInCBlock, fetch);
     }
 }
@@ -501,7 +501,7 @@
     } else {
 	const size_t buf_sz = pd->cd->mask_size - fetch->mask_offset;
 	assert(buf_sz > 0);
-	storeClientCopy(fetch->entry,
+	storeClientCopy(fetch->sc, fetch->entry,
 	    fetch->offset,
 	    fetch->offset,
 	    buf_sz,
@@ -684,7 +684,7 @@
 
     if (fetch->old_entry) {
 	debug(72, 2) ("peerDigestFetchFinish: deleting old entry\n");
-	storeUnregister(fetch->old_entry, fetch);
+	storeUnregister(fetch->sc, fetch->old_entry, fetch);
 	storeReleaseRequest(fetch->old_entry);
 	storeUnlockObject(fetch->old_entry);
 	fetch->old_entry = NULL;
@@ -696,7 +696,7 @@
     Counter.cd.msgs_recv += fetch->recv.msg;
 
     /* unlock everything */
-    storeUnregister(fetch->entry, fetch);
+    storeUnregister(fetch->sc, fetch->entry, fetch);
     storeUnlockObject(fetch->entry);
     requestUnlink(fetch->request);
     fetch->entry = NULL;
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.1.1.3.10.8.2.3
retrieving revision 1.1.1.3.10.8.2.4
diff -u -r1.1.1.3.10.8.2.3 -r1.1.1.3.10.8.2.4
--- squid/src/protos.h	2 May 2000 23:21:53 -0000	1.1.1.3.10.8.2.3
+++ squid/src/protos.h	8 May 2000 18:02:08 -0000	1.1.1.3.10.8.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.1.1.3.10.8.2.3 2000/05/02 23:21:53 hno Exp $
+ * $Id: protos.h,v 1.1.1.3.10.8.2.4 2000/05/08 18:02:08 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -809,14 +809,6 @@
 extern void storeLockObject(StoreEntry *);
 extern void storeRelease(StoreEntry *);
 extern int storeUnlockObject(StoreEntry *);
-extern int storeUnregister(StoreEntry *, void *);
-extern void storeClientCopy(StoreEntry * e,
-    off_t seen_offset,
-    off_t copy_offset,
-    size_t size,
-    char *buf,
-    STCB * callback,
-    void *data);
 extern int storePendingNClients(const StoreEntry *);
 extern EVH storeMaintainSwapSpace;
 extern void storeExpireNow(StoreEntry *);
@@ -826,7 +818,6 @@
 extern void storeNegativeCache(StoreEntry *);
 extern void storeFreeMemory(void);
 extern int expiresMoreThan(time_t, time_t);
-extern int storeClientCopyPending(StoreEntry *, void *);
 extern void InvokeHandlers(StoreEntry *);
 extern int storeEntryValidToSend(StoreEntry *);
 extern void storeTimestampsSet(StoreEntry *);
@@ -968,11 +959,13 @@
 /*
  * store_client.c
  */
+#if STORE_CLIENT_LIST_DEBUG
 extern store_client *storeClientListSearch(const MemObject * mem, void *data);
-extern void storeClientListAdd(StoreEntry * e, void *data);
-extern void storeClientCopy(StoreEntry *, off_t, off_t, size_t, char *, STCB *, void *);
-extern int storeClientCopyPending(StoreEntry * e, void *data);
-extern int storeUnregister(StoreEntry * e, void *data);
+#endif
+extern store_client *storeClientListAdd(StoreEntry * e, void *data);
+extern void storeClientCopy(store_client *, StoreEntry *, off_t, off_t, size_t, char *, STCB *, void *);
+extern int storeClientCopyPending(store_client *, StoreEntry * e, void *data);
+extern int storeUnregister(store_client *sc, StoreEntry * e, void *data);
 extern off_t storeLowestMemReaderOffset(const StoreEntry * entry);
 extern void InvokeHandlers(StoreEntry * e);
 extern int storePendingNClients(const StoreEntry * e);
@@ -1160,7 +1153,7 @@
 extern void delayBytesIn(delay_id, int qty);
 extern int delayMostBytesWanted(const MemObject * mem, int max);
 extern delay_id delayMostBytesAllowed(const MemObject * mem);
-extern void delaySetStoreClient(StoreEntry * e, void *data, delay_id delay_id);
+extern void delaySetStoreClient(store_client *sc, delay_id delay_id);
 extern void delayRegisterDelayIdPtr(delay_id * loc);
 extern void delayUnregisterDelayIdPtr(delay_id * loc);
 #endif
Index: squid/src/pump.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/pump.c,v
retrieving revision 1.1.1.3.10.2.2.1
retrieving revision 1.1.1.3.10.2.2.2
diff -u -r1.1.1.3.10.2.2.1 -r1.1.1.3.10.2.2.2
--- squid/src/pump.c	2 May 2000 22:50:29 -0000	1.1.1.3.10.2.2.1
+++ squid/src/pump.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.2.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: pump.c,v 1.1.1.3.10.2.2.1 2000/05/02 22:50:29 hno Exp $
+ * $Id: pump.c,v 1.1.1.3.10.2.2.2 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 61    PUMP handler
  * AUTHOR: Kostas Anagnostakis
@@ -40,6 +40,7 @@
 struct _PumpStateData {
     FwdState *fwd;
     request_t *req;
+    store_client *sc;		/* The store client we're using */
     int c_fd;			/* client fd */
     int s_fd;			/* server end */
     int rcvd;			/* bytes received from client */
@@ -91,10 +92,10 @@
     snprintf(new_key, MAX_URL + 5, "%s|Pump", uri);
     cbdataAdd(p, cbdataXfree, 0);
     p->request_entry = storeCreateEntry(new_key, new_key, flags, r->method);
-    storeClientListAdd(p->request_entry, p);
+    p->sc = storeClientListAdd(p->request_entry, p);
     EBIT_SET(p->request_entry->flags, ENTRY_DONT_LOG);
 #if DELAY_POOLS
-    delaySetStoreClient(p->request_entry, p, delayClient(r));
+    delaySetStoreClient(p->sc, delayClient(r));
 #endif
     /*
      * initialize data structure
@@ -163,7 +164,7 @@
     if (p->sent == p->req->content_length) {
 	pumpServerCopyComplete(p->s_fd, NULL, 0, DISK_OK, p);
     } else {
-	storeClientCopy(p->request_entry, p->sent, p->sent, 4096,
+	storeClientCopy(p->sc, p->request_entry, p->sent, p->sent, 4096,
 	    memAllocate(MEM_4K_BUF),
 	    pumpServerCopy, p);
     }
@@ -211,7 +212,7 @@
     p->sent += size;
     assert(p->sent <= p->req->content_length);
     if (p->sent < p->req->content_length) {
-	storeClientCopy(p->request_entry, p->sent, p->sent, 4096,
+	storeClientCopy(p->sc, p->request_entry, p->sent, p->sent, 4096,
 	    memAllocate(MEM_4K_BUF),
 	    pumpServerCopy, p);
 	return;
@@ -326,7 +327,7 @@
     assert(!p->flags.closing);
     p->flags.closing = 1;
     if (req != NULL && req->store_status == STORE_PENDING) {
-	storeUnregister(req, p);
+	storeUnregister(p->sc, req, p);
     }
     if (rep != NULL && rep->store_status == STORE_PENDING) {
 	ErrorState *err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
@@ -366,7 +367,7 @@
     req = p->request_entry;
     rep = p->reply_entry;
     if (req != NULL) {
-	storeUnregister(req, p);
+	storeUnregister(p->sc, req, p);
 	storeUnlockObject(req);
 	p->request_entry = NULL;
     }
Index: squid/src/stat.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/stat.c,v
retrieving revision 1.1.1.3.10.4
retrieving revision 1.1.1.3.10.4.2.1
diff -u -r1.1.1.3.10.4 -r1.1.1.3.10.4.2.1
--- squid/src/stat.c	20 Apr 2000 18:14:23 -0000	1.1.1.3.10.4
+++ squid/src/stat.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.4.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: stat.c,v 1.1.1.3.10.4 2000/04/20 18:14:23 hno Exp $
+ * $Id: stat.c,v 1.1.1.3.10.4.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -255,6 +255,7 @@
     MemObject *mem = e->mem_obj;
     int i;
     struct _store_client *sc;
+    dlink_node *node;
     storeAppendPrintf(s, "KEY %s\n", storeKeyText(e->key));
     if (mem)
 	storeAppendPrintf(s, "\t%s %s\n",
@@ -276,7 +277,8 @@
 	if (mem->swapout.sio)
 	    storeAppendPrintf(s, "\tswapout: %d bytes written\n",
 		(int) storeOffset(mem->swapout.sio));
-	for (i = 0, sc = &mem->clients[i]; sc != NULL; sc = sc->next, i++) {
+        for (i = 0, node = mem->clients.head; node; node = node->next, i++) {
+            sc = (store_client *)node->data;
 	    if (sc->callback_data == NULL)
 		continue;
 	    storeAppendPrintf(s, "\tClient #%d, %p\n", i, sc->callback_data);
Index: squid/src/store.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store.c,v
retrieving revision 1.1.1.3.10.8.2.2
retrieving revision 1.1.1.3.10.8.2.3
diff -u -r1.1.1.3.10.8.2.2 -r1.1.1.3.10.8.2.3
--- squid/src/store.c	2 May 2000 23:01:48 -0000	1.1.1.3.10.8.2.2
+++ squid/src/store.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.8.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.c,v 1.1.1.3.10.8.2.2 2000/05/02 23:01:48 hno Exp $
+ * $Id: store.c,v 1.1.1.3.10.8.2.3 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
@@ -166,7 +166,7 @@
      * There is no way to abort FD-less clients, so they might
      * still have mem->clients set if mem->fd == -1
      */
-    assert(mem->fd == -1 || mem->clients == NULL);
+    assert(mem->fd == -1 || mem->clients.head == NULL);
     httpReplyDestroy(mem->reply);
     requestUnlink(mem->request);
     mem->request = NULL;
Index: squid/src/store_client.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_client.c,v
retrieving revision 1.1.1.3.10.4.2.1
retrieving revision 1.1.1.3.10.4.2.2
diff -u -r1.1.1.3.10.4.2.1 -r1.1.1.3.10.4.2.2
--- squid/src/store_client.c	2 May 2000 22:50:29 -0000	1.1.1.3.10.4.2.1
+++ squid/src/store_client.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.4.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_client.c,v 1.1.1.3.10.4.2.1 2000/05/02 22:50:29 hno Exp $
+ * $Id: store_client.c,v 1.1.1.3.10.4.2.2 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Client-Side Interface
  * AUTHOR: Duane Wessels
@@ -56,24 +56,30 @@
 storeClientWaiting(const StoreEntry * e)
 {
     MemObject *mem = e->mem_obj;
+    dlink_node *node;
     store_client *sc;
-    for (sc = mem->clients; sc; sc = sc->next) {
+    for (node = mem->clients.head; node; node = node->next) {
+        sc = (store_client *)node->data;
 	if (sc->callback_data != NULL)
 	    return 1;
     }
     return 0;
 }
 
+#if STORE_CLIENT_LIST_DEBUG
 store_client *
 storeClientListSearch(const MemObject * mem, void *data)
 {
-    store_client *sc;
-    for (sc = mem->clients; sc; sc = sc->next) {
+    dlink_node *node;
+    store_client *sc = NULL;
+    for (node = mem->clients.head; node; node = node->next) {
+        sc = (store_client *)node->data;
 	if (sc->callback_data == data)
-	    break;
+	    return sc;
     }
-    return sc;
+    return NULL;
 }
+#endif
 
 static store_client_t
 storeClientType(StoreEntry * e)
@@ -115,15 +121,16 @@
 }
 
 /* add client with fd to client list */
-void
+store_client *
 storeClientListAdd(StoreEntry * e, void *data)
 {
     MemObject *mem = e->mem_obj;
-    store_client **T;
     store_client *sc;
     assert(mem);
+#if STORE_CLIENT_LIST_DEBUG
     if (storeClientListSearch(mem, data) != NULL)
-	return;
+	assert(1==0); /* XXX die! */
+#endif
     e->refcount++;
     mem->nclients++;
     sc = memAllocate(MEM_STORE_CLIENT);
@@ -139,11 +146,11 @@
 	/* assert we'll be able to get the data we want */
 	/* maybe we should open swapin_fd here */
 	assert(e->swap_filen > -1 || storeSwapOutAble(e));
-    for (T = &mem->clients; *T; T = &(*T)->next);
-    *T = sc;
+    dlinkAdd(sc, &sc->node, &mem->clients);
 #if DELAY_POOLS
     sc->delay_id = 0;
 #endif
+    return sc;
 }
 
 static void
@@ -171,7 +178,8 @@
 
 /* copy bytes requested by the client */
 void
-storeClientCopy(StoreEntry * e,
+storeClientCopy(store_client *sc,
+    StoreEntry * e,
     off_t seen_offset,
     off_t copy_offset,
     size_t size,
@@ -179,7 +187,6 @@
     STCB * callback,
     void *data)
 {
-    store_client *sc;
     assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
     debug(20, 3) ("storeClientCopy: %s, seen %d, want %d, size %d, cb %p, cbdata %p\n",
 	storeKeyText(e->key),
@@ -188,9 +195,12 @@
 	(int) size,
 	callback,
 	data);
-    sc = storeClientListSearch(e->mem_obj, data);
     assert(sc != NULL);
+#if STORE_CLIENT_LIST_DEBUG
+    assert(sc == storeClientListSearch(e->mem_obj, data));
+#endif
     assert(sc->callback == NULL);
+    assert(sc->entry == e);
     sc->copy_offset = copy_offset;
     sc->seen_offset = seen_offset;
     sc->callback = callback;
@@ -457,10 +467,12 @@
 }
 
 int
-storeClientCopyPending(StoreEntry * e, void *data)
+storeClientCopyPending(store_client *sc, StoreEntry * e, void *data)
 {
-    /* return 1 if there is a callback registered for this client */
-    store_client *sc = storeClientListSearch(e->mem_obj, data);
+#if STORE_CLIENT_LIST_DEBUG
+    assert(sc == storeClientListSearch(e->mem_obj, data));
+#endif
+    assert(sc->entry == e);
     if (sc == NULL)
 	return 0;
     if (sc->callback == NULL)
@@ -468,52 +480,55 @@
     return 1;
 }
 
+/*
+ * This routine hasn't been optimised to take advantage of the
+ * passed sc. Yet.
+ */
 int
-storeUnregister(StoreEntry * e, void *data)
+storeUnregister(store_client *sc, StoreEntry * e, void *data)
 {
     MemObject *mem = e->mem_obj;
-    store_client *sc;
-    store_client **S;
+#if STORE_CLIENT_LIST_DEBUG
+    assert(sc == storeClientListSearch(e->mem_obj, data));
+#endif
     if (mem == NULL)
-	return 0;
+        return 0;
     debug(20, 3) ("storeUnregister: called for '%s'\n", storeKeyText(e->key));
-    for (S = &mem->clients; (sc = *S) != NULL; S = &(*S)->next) {
-	if (sc->callback_data == data)
-	    break;
-    }
     if (sc == NULL)
-	return 0;
-    if (sc == mem->clients) {
-	/*
-	 * If we are unregistering the _first_ client for this
-	 * entry, then we have to reset the client FD to -1.
-	 */
-	mem->fd = -1;
+        return 0;
+    if (mem->clients.head == NULL)
+        return 0;
+    if (sc == (store_client *)mem->clients.head->data) {
+        /*
+         * If we are unregistering the _first_ client for this
+         * entry, then we have to reset the client FD to -1.
+         */
+        mem->fd = -1;
     }
-    *S = sc->next;
+    dlinkDelete(&sc->node, &mem->clients);
     mem->nclients--;
     if (e->store_status == STORE_OK && e->swap_status != SWAPOUT_DONE)
-	storeSwapOut(e);
+        storeSwapOut(e);
     if (sc->swapin_sio) {
-	storeClose(sc->swapin_sio);
-	cbdataUnlock(sc->swapin_sio);
-	sc->swapin_sio = NULL;
+        storeClose(sc->swapin_sio);
+        cbdataUnlock(sc->swapin_sio);
+        sc->swapin_sio = NULL;
     }
     if (NULL != sc->callback) {
-	/* callback with ssize = -1 to indicate unexpected termination */
-	debug(20, 3) ("storeUnregister: store_client for %s has a callback\n",
-	    mem->url);
-	storeClientCallback(sc, -1);
+        /* callback with ssize = -1 to indicate unexpected termination */
+        debug(20, 3) ("storeUnregister: store_client for %s has a callback\n",
+            mem->url);
+        storeClientCallback(sc, -1);
     }
 #if DELAY_POOLS
     delayUnregisterDelayIdPtr(&sc->delay_id);
 #endif
-    cbdataUnlock(sc->callback_data);	/* we're done with it now */
+    cbdataUnlock(sc->callback_data);    /* we're done with it now */
     /*assert(!sc->flags.disk_io_pending); */
     cbdataFree(sc);
     assert(e->lock_count > 0);
     if (mem->nclients == 0)
-	CheckQuickAbort(e);
+        CheckQuickAbort(e);
     return 1;
 }
 
@@ -523,9 +538,12 @@
     const MemObject *mem = entry->mem_obj;
     off_t lowest = mem->inmem_hi + 1;
     store_client *sc;
-    store_client *nx = NULL;
-    for (sc = mem->clients; sc; sc = nx) {
-	nx = sc->next;
+    dlink_node *nx = NULL;
+    dlink_node *node;
+
+    for (node = mem->clients.head; node; node = nx) {
+        sc = (store_client *)node->data;
+	nx = node->next;
 	if (sc->callback_data == NULL)	/* open slot */
 	    continue;
 	if (sc->type != STORE_MEM_CLIENT)
@@ -546,12 +564,14 @@
     int i = 0;
     MemObject *mem = e->mem_obj;
     store_client *sc;
-    store_client *nx = NULL;
-    assert(mem->clients != NULL || mem->nclients == 0);
+    dlink_node *nx = NULL;
+    dlink_node *node;
+
     debug(20, 3) ("InvokeHandlers: %s\n", storeKeyText(e->key));
     /* walk the entire list looking for valid callbacks */
-    for (sc = mem->clients; sc; sc = nx) {
-	nx = sc->next;
+    for (node = mem->clients.head; node; node = nx) {
+        sc = (store_client *)node->data;
+	nx = node->next;
 	debug(20, 3) ("InvokeHandlers: checking client #%d\n", i++);
 	if (sc->callback_data == NULL)
 	    continue;
Index: squid/src/store_digest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_digest.c,v
retrieving revision 1.1.1.3.6.1
retrieving revision 1.1.1.3.6.1.2.1
diff -u -r1.1.1.3.6.1 -r1.1.1.3.6.1.2.1
--- squid/src/store_digest.c	20 Apr 2000 18:14:23 -0000	1.1.1.3.6.1
+++ squid/src/store_digest.c	8 May 2000 18:02:08 -0000	1.1.1.3.6.1.2.1
@@ -1,5 +1,5 @@
 /*
- * $Id: store_digest.c,v 1.1.1.3.6.1 2000/04/20 18:14:23 hno Exp $
+ * $Id: store_digest.c,v 1.1.1.3.6.1.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 71    Store Digest Manager
  * AUTHOR: Alex Rousskov
@@ -230,10 +230,12 @@
      * idea: skip objects that are going to be purged before the next
      * update.
      */
+#if 0 /* This code isn't applicable anymore, we can't fix it atm either :( */
 #if !HEAP_REPLACEMENT
     if ((squid_curtime + Config.digest.rebuild_period) - e->lastref > storeExpiredReferenceAge())
 	return 0;
 #endif
+#endif
     return 1;
 }
 
Index: squid/src/store_swapout.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_swapout.c,v
retrieving revision 1.1.1.3.10.5
retrieving revision 1.1.1.3.10.5.2.1
diff -u -r1.1.1.3.10.5 -r1.1.1.3.10.5.2.1
--- squid/src/store_swapout.c	20 Apr 2000 18:14:23 -0000	1.1.1.3.10.5
+++ squid/src/store_swapout.c	8 May 2000 18:02:08 -0000	1.1.1.3.10.5.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapout.c,v 1.1.1.3.10.5 2000/04/20 18:14:23 hno Exp $
+ * $Id: store_swapout.c,v 1.1.1.3.10.5.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Swapout Functions
  * AUTHOR: Duane Wessels
@@ -346,7 +346,7 @@
 int
 storeSwapOutAble(const StoreEntry * e)
 {
-    store_client *sc;
+    dlink_node *node;
     if (e->mem_obj->swapout.sio != NULL)
 	return 1;
     if (e->mem_obj->inmem_lo > 0)
@@ -355,9 +355,10 @@
      * If there are DISK clients, we must write to disk
      * even if its not cachable
      */
-    for (sc = e->mem_obj->clients; sc; sc = sc->next)
-	if (sc->type == STORE_DISK_CLIENT)
-	    return 1;
+    for (node = e->mem_obj->clients.head; node; node = node->next) {
+        if (((store_client *)node->data)->type == STORE_DISK_CLIENT)
+            return 1;
+    }
     if (store_dirs_rebuilding)
 	if (!EBIT_TEST(e->flags, ENTRY_SPECIAL))
 	    return 0;
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.1.1.3.10.8.2.4
retrieving revision 1.1.1.3.10.8.2.5
diff -u -r1.1.1.3.10.8.2.4 -r1.1.1.3.10.8.2.5
--- squid/src/structs.h	2 May 2000 22:50:29 -0000	1.1.1.3.10.8.2.4
+++ squid/src/structs.h	8 May 2000 18:02:08 -0000	1.1.1.3.10.8.2.5
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.1.1.3.10.8.2.4 2000/05/02 22:50:29 hno Exp $
+ * $Id: structs.h,v 1.1.1.3.10.8.2.5 2000/05/08 18:02:08 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -860,6 +860,7 @@
 struct _clientHttpRequest {
     ConnStateData *conn;
     request_t *request;		/* Parsed URL ... */
+    store_client *sc;		/* The store_client we're using */
     char *uri;
     char *log_uri;
     struct {
@@ -1001,6 +1002,8 @@
     PeerDigest *pd;
     StoreEntry *entry;
     StoreEntry *old_entry;
+    store_client *sc;
+    store_client *old_sc;
     request_t *request;
     int offset;
     int mask_offset;
@@ -1272,10 +1275,10 @@
 	unsigned int store_copying:1;
 	unsigned int copy_event_pending:1;
     } flags;
-    store_client *next;
 #if DELAY_POOLS
     delay_id delay_id;
 #endif
+    dlink_node node;
 };
 
 
@@ -1286,7 +1289,7 @@
     mem_hdr data_hdr;
     off_t inmem_hi;
     off_t inmem_lo;
-    store_client *clients;
+    dlink_list clients;
     int nclients;
     struct {
 	off_t queue_offset;	/* relative to in-mem data */
Index: squid/src/urn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/urn.c,v
retrieving revision 1.1.1.3.6.1
retrieving revision 1.1.1.3.6.1.2.1
diff -u -r1.1.1.3.6.1 -r1.1.1.3.6.1.2.1
--- squid/src/urn.c	20 Apr 2000 18:14:23 -0000	1.1.1.3.6.1
+++ squid/src/urn.c	8 May 2000 18:02:08 -0000	1.1.1.3.6.1.2.1
@@ -1,7 +1,7 @@
 
 /*
  *
- * $Id: urn.c,v 1.1.1.3.6.1 2000/04/20 18:14:23 hno Exp $
+ * $Id: urn.c,v 1.1.1.3.6.1.2.1 2000/05/08 18:02:08 hno Exp $
  *
  * DEBUG: section 52    URN Parsing
  * AUTHOR: Kostas Anagnostakis
@@ -38,6 +38,7 @@
 
 typedef struct {
     StoreEntry *entry;
+    store_client *sc;
     StoreEntry *urlres_e;
     request_t *request;
     request_t *urlres_r;
@@ -137,15 +138,15 @@
     httpHeaderPutStr(&urlres_r->header, HDR_ACCEPT, "text/plain");
     if ((urlres_e = storeGetPublic(urlres, METHOD_GET)) == NULL) {
 	urlres_e = storeCreateEntry(urlres, urlres, null_request_flags, METHOD_GET);
-	storeClientListAdd(urlres_e, urnState);
+	urnState->sc = storeClientListAdd(urlres_e, urnState);
 	fwdStart(-1, urlres_e, urlres_r);
     } else {
 	storeLockObject(urlres_e);
-	storeClientListAdd(urlres_e, urnState);
+	urnState->sc = storeClientListAdd(urlres_e, urnState);
     }
     urnState->urlres_e = urlres_e;
     urnState->urlres_r = requestLink(urlres_r);
-    storeClientCopy(urlres_e,
+    storeClientCopy(urnState->sc, urlres_e,
 	0,
 	0,
 	4096,
@@ -199,7 +200,7 @@
 	return;
     }
     if (urlres_e->store_status == STORE_PENDING && size < SM_PAGE_SIZE) {
-	storeClientCopy(urlres_e,
+	storeClientCopy(urnState->sc, urlres_e,
 	    size,
 	    0,
 	    SM_PAGE_SIZE,
@@ -289,7 +290,7 @@
     }
     safe_free(urls);
     /* mb was absorbed in httpBodySet call, so we must not clean it */
-    storeUnregister(urlres_e, urnState);
+    storeUnregister(urnState->sc, urlres_e, urnState);
     storeUnlockObject(urlres_e);
     storeUnlockObject(urnState->entry);
     requestUnlink(urnState->request);
