--------------------- PatchSet 10028 Date: 2007/09/24 14:29:37 Author: adri Branch: store_copy Tag: (none) Log: Start fleshing out copy-less primitives for the store client. Members: src/protos.h:1.146->1.146.2.1 src/stmem.c:1.10->1.10.2.1 src/store_client.c:1.25->1.25.10.1 src/structs.h:1.158->1.158.2.1 src/typedefs.h:1.43->1.43.2.1 Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.146 retrieving revision 1.146.2.1 diff -u -r1.146 -r1.146.2.1 --- squid/src/protos.h 23 Sep 2007 14:51:44 -0000 1.146 +++ squid/src/protos.h 24 Sep 2007 14:29:37 -0000 1.146.2.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.146 2007/09/23 14:51:44 squidadm Exp $ + * $Id: protos.h,v 1.146.2.1 2007/09/24 14:29:37 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -897,6 +897,9 @@ extern void stmemFreeData(mem_hdr *); extern void stmemNodeFree(void *); extern char *stmemNodeGet(mem_node *); +extern int stmemRef(const mem_hdr *mem, squid_off_t offset, mem_node_ref *r); +extern void stmemUnref(mem_node_ref *r); + /* ----------------------------------------------------------------- */ @@ -1083,6 +1086,8 @@ */ extern store_client *storeClientRegister(StoreEntry * e, void *data); extern void storeClientCopy(store_client *, StoreEntry *, squid_off_t, squid_off_t, size_t, char *, STCB *, void *); +extern void storeClientRef(store_client *, StoreEntry *, squid_off_t, squid_off_t, size_t, STNCB *, void *); +extern void storeClientDeref(store_client *, mem_node_ref *r); extern int storeClientCopyPending(store_client *, StoreEntry * e, void *data); extern int storeClientUnregister(store_client * sc, StoreEntry * e, void *data); extern squid_off_t storeLowestMemReaderOffset(const StoreEntry * entry); Index: squid/src/stmem.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/stmem.c,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -u -r1.10 -r1.10.2.1 --- squid/src/stmem.c 23 Sep 2007 07:53:08 -0000 1.10 +++ squid/src/stmem.c 24 Sep 2007 14:29:38 -0000 1.10.2.1 @@ -1,6 +1,6 @@ /* - * $Id: stmem.c,v 1.10 2007/09/23 07:53:08 squidadm Exp $ + * $Id: stmem.c,v 1.10.2.1 2007/09/24 14:29:38 adri Exp $ * * DEBUG: section 19 Store Memory Primitives * AUTHOR: Harvest Derived @@ -135,6 +135,56 @@ } } +/* + * Fetch a page from the store mem. + * + * The page data may not start from the same offset given here; the + * mem_node reference returned will include a node pointer and offset + * into the buffer so the client 'knows' where to start. + * + * The reference taking is a bit of a hack (and the free'ing is also + * quite a bit of a hack!) but it'll have to suffice until a better + * buffer management system replaces this stuff. + * + * Please note that the stmem code doesn't at all attempt to make + * sure the memobject you're copying from actually has data where + * you've asked for it. the store_client.c and store_swapout.c + * routines all do magic to keep that in check. + */ +int +stmemRef(const mem_hdr *mem, squid_off_t offset, mem_node_ref *r) +{ + mem_node *p = mem->head; + squid_off_t t_off = mem->origin_offset; + int bytes_into_this_packet = 0; + + debug(19, 6) ("memRef: offset %" PRINTF_OFF_T "\n", offset); + if (p == NULL) + return 0; + /* Seek our way into store */ + while ((t_off + p->len) < offset) { + t_off += p->len; + if (!p->next) { + debug(19, 1) ("memRef: p->next == NULL\n"); + return 0; + } + assert(p->next); + p = p->next; + } + bytes_into_this_packet = offset - t_off; + r->node = (mem_node *) stmemNodeGet(p); + r->offset = bytes_into_this_packet; + return 1; +} + +void +stmemUnref(mem_node_ref *r) +{ + stmemNodeFree((void *) r->node); + r->node = NULL; + r->offset = -1; +} + ssize_t stmemCopy(const mem_hdr * mem, squid_off_t offset, char *buf, size_t size) { Index: squid/src/store_client.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store_client.c,v retrieving revision 1.25 retrieving revision 1.25.10.1 diff -u -r1.25 -r1.25.10.1 --- squid/src/store_client.c 26 Jan 2007 02:52:44 -0000 1.25 +++ squid/src/store_client.c 24 Sep 2007 14:29:38 -0000 1.25.10.1 @@ -1,6 +1,6 @@ /* - * $Id: store_client.c,v 1.25 2007/01/26 02:52:44 squidadm Exp $ + * $Id: store_client.c,v 1.25.10.1 2007/09/24 14:29:38 adri Exp $ * * DEBUG: section 20 Storage Manager Client-Side Interface * AUTHOR: Duane Wessels @@ -136,14 +136,27 @@ storeClientCallback(store_client * sc, ssize_t sz) { STCB *callback = sc->callback; + STNCB *new_callback = sc->new_callback; void *cbdata = sc->callback_data; char *buf = sc->copy_buf; - assert(sc->callback); + mem_node_ref nr; + + assert(sc->callback || sc->new_callback); sc->callback = NULL; + sc->new_callback = NULL; sc->callback_data = NULL; sc->copy_buf = NULL; - if (cbdataValid(cbdata)) - callback(cbdata, buf, sz); + nr = sc->node_ref; + sc->node_ref.node = NULL; + sc->node_ref.offset = -1; + if (cbdataValid(cbdata)) { + if (callback) + callback(cbdata, buf, sz); + else if (new_callback) + new_callback(cbdata, nr); + else + fatal("storeClientCallback: neither callback handler set!\n"); + } cbdataUnlock(cbdata); } @@ -159,6 +172,50 @@ } /* copy bytes requested by the client */ + +void +storeClientRef(store_client *sc, + StoreEntry * e, + squid_off_t seen_offset, + squid_off_t copy_offset, + size_t size, + STNCB * callback, + void *data) +{ + assert(!EBIT_TEST(e->flags, ENTRY_ABORTED)); + debug(20, 3) ("storeClientRef: %s, seen %" PRINTF_OFF_T ", want %" PRINTF_OFF_T ", size %d, cb %p, cbdata %p\n", + storeKeyText(e->hash.key), + seen_offset, + copy_offset, + (int) size, + callback, + data); + assert(sc != NULL); +#if STORE_CLIENT_LIST_DEBUG + assert(sc == storeClientListSearch(e->mem_obj, data)); +#endif + assert(sc->callback == NULL); + assert(sc->new_callback == NULL); + assert(sc->entry == e); + sc->callback = NULL; + sc->seen_offset = seen_offset; + sc->new_callback = callback; + sc->callback_data = data; + cbdataLock(sc->callback_data); + sc->copy_buf = NULL; + sc->copy_size = size; + sc->copy_offset = copy_offset; + sc->node_ref.node = NULL; + sc->node_ref.offset = -1; + /* If the read is being deferred, run swapout in case this client has the + * lowest seen_offset. storeSwapOut() frees the memory and clears the + * ENTRY_DEFER_READ bit if necessary */ + if (EBIT_TEST(e->flags, ENTRY_DEFER_READ)) { + storeSwapOut(e); + } + storeClientCopy2(e, sc); +} + void storeClientCopy(store_client * sc, StoreEntry * e, @@ -182,7 +239,9 @@ assert(sc == storeClientListSearch(e->mem_obj, data)); #endif assert(sc->callback == NULL); + assert(sc->new_callback == NULL); assert(sc->entry == e); + sc->new_callback = NULL; sc->seen_offset = seen_offset; sc->callback = callback; sc->callback_data = data; @@ -190,6 +249,8 @@ sc->copy_buf = buf; sc->copy_size = size; sc->copy_offset = copy_offset; + sc->node_ref.node = NULL; + sc->node_ref.offset = -1; /* If the read is being deferred, run swapout in case this client has the * lowest seen_offset. storeSwapOut() frees the memory and clears the * ENTRY_DEFER_READ bit if necessary */ @@ -335,6 +396,8 @@ assert(sc->callback != NULL); assert(!sc->flags.disk_io_pending); sc->flags.disk_io_pending = 1; + if (sc->new_callback) + fatal("For now: storeClientFileRead needs fixing to work in the storeClientRef() case!!\n"); if (mem->swap_hdr_sz == 0) { storeRead(sc->swapin_sio, sc->copy_buf, @@ -666,3 +729,9 @@ statCounter.aborted_requests++; storeAbort(entry); } + +void +storeClientDeref(store_client *sc, mem_node_ref *r) +{ + stmemUnref(r); +} Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.158 retrieving revision 1.158.2.1 diff -u -r1.158 -r1.158.2.1 --- squid/src/structs.h 23 Sep 2007 14:51:45 -0000 1.158 +++ squid/src/structs.h 24 Sep 2007 14:29:38 -0000 1.158.2.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.158 2007/09/23 14:51:45 squidadm Exp $ + * $Id: structs.h,v 1.158.2.1 2007/09/24 14:29:38 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1637,8 +1637,10 @@ squid_off_t copy_offset; squid_off_t seen_offset; size_t copy_size; + mem_node_ref node_ref; char *copy_buf; STCB *callback; + STNCB *new_callback; void *callback_data; StoreEntry *entry; /* ptr to the parent StoreEntry, argh! */ storeIOState *swapin_sio; Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.43 retrieving revision 1.43.2.1 diff -u -r1.43 -r1.43.2.1 --- squid/src/typedefs.h 18 Sep 2007 14:52:32 -0000 1.43 +++ squid/src/typedefs.h 24 Sep 2007 14:29:38 -0000 1.43.2.1 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.43 2007/09/18 14:52:32 squidadm Exp $ + * $Id: typedefs.h,v 1.43.2.1 2007/09/24 14:29:38 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -61,6 +61,16 @@ #define SIZEOF_SQUID_FILE_SZ SIZEOF_SIZE_T #endif +struct _mem_node_ref { + struct _mem_node *node; + /* + * the caller asked for a specific offset into the object; + * this particular offset is the offset into the above mem_node + * to get at said data. + */ + int offset; +}; + typedef struct { squid_off_t bytes; squid_off_t kb; @@ -163,6 +173,7 @@ typedef struct _MemBuf MemBuf; typedef struct _mem_node mem_node; typedef struct _mem_hdr mem_hdr; +typedef struct _mem_node_ref mem_node_ref; typedef struct _store_client store_client; typedef struct _MemObject MemObject; typedef struct _StoreEntry StoreEntry; @@ -277,6 +288,7 @@ typedef void SIH(storeIOState *, void *); /* swap in */ typedef int QS(const void *, const void *); /* qsort */ typedef void STCB(void *, char *, ssize_t); /* store callback */ +typedef void STNCB(void *, struct _mem_node_ref r); /* new store callback */ typedef void STABH(void *); typedef void ERCB(int fd, void *, size_t); typedef void OBJH(StoreEntry *);