⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 store_client.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: store_client.c,v 1.59.2.8 1999/06/19 16:19:34 wessels Exp $ * * DEBUG: section 20    Storage Manager Client-Side Interface * AUTHOR: Duane Wessels * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please 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. * */#include "squid.h"/* * NOTE: 'Header' refers to the swapfile metadata header. *       'Body' refers to the swapfile body, which is the full *        HTTP reply (including HTTP headers and body). */static DRCB storeClientReadBody;static DRCB storeClientReadHeader;static SIH storeClientFileOpened;static void storeClientCopy2(StoreEntry * e, store_client * sc);static void storeClientFileRead(store_client * sc);static EVH storeClientCopyEvent;static store_client_t storeClientType(StoreEntry *);static int CheckQuickAbort2(StoreEntry * entry);static void CheckQuickAbort(StoreEntry * entry);/* check if there is any client waiting for this object at all *//* return 1 if there is at least one client */intstoreClientWaiting(const StoreEntry * e){    MemObject *mem = e->mem_obj;    store_client *sc;    for (sc = mem->clients; sc; sc = sc->next) {	if (sc->callback_data != NULL)	    return 1;    }    return 0;}store_client *storeClientListSearch(const MemObject * mem, void *data){    store_client *sc;    for (sc = mem->clients; sc; sc = sc->next) {	if (sc->callback_data == data)	    break;    }    return sc;}static store_client_tstoreClientType(StoreEntry * e){    MemObject *mem = e->mem_obj;    if (mem->inmem_lo)	return STORE_DISK_CLIENT;    if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {	/* I don't think we should be adding clients to aborted entries */	debug(20, 1) ("storeClientType: adding to ENTRY_ABORTED entry\n");	return STORE_MEM_CLIENT;    }    if (e->store_status == STORE_OK) {	if (mem->inmem_lo == 0 && mem->inmem_hi > 0)	    return STORE_MEM_CLIENT;	else	    return STORE_DISK_CLIENT;    }    /* here and past, entry is STORE_PENDING */    /*     * If this is the first client, let it be the mem client     */    else if (mem->nclients == 1)	return STORE_MEM_CLIENT;    /*     * otherwise, make subsequent clients read from disk so they     * can not delay the first, and vice-versa.     */    else	return STORE_DISK_CLIENT;}/* add client with fd to client list */voidstoreClientListAdd(StoreEntry * e, void *data){    MemObject *mem = e->mem_obj;    store_client **T;    store_client *sc;    assert(mem);    if (storeClientListSearch(mem, data) != NULL)	return;    mem->nclients++;    sc = memAllocate(MEM_STORE_CLIENT);    cbdataAdd(sc, memFree, MEM_STORE_CLIENT);	/* sc is callback_data for file_read */    sc->callback_data = data;    sc->seen_offset = 0;    sc->copy_offset = 0;    sc->swapin_fd = -1;    sc->flags.disk_io_pending = 0;    sc->entry = e;    sc->type = storeClientType(e);    if (sc->type == STORE_DISK_CLIENT)	/* assert we'll be able to get the data we want */	/* maybe we should open swapin_fd here */	assert(e->swap_file_number > -1 || storeSwapOutAble(e));    for (T = &mem->clients; *T; T = &(*T)->next);    *T = sc;#if DELAY_POOLS    sc->delay_id = 0;#endif}static voidstoreClientCopyEvent(void *data){    store_client *sc = data;    debug(20, 3) ("storeClientCopyEvent: Running\n");    sc->flags.copy_event_pending = 0;    if (!sc->callback)	return;    storeClientCopy2(sc->entry, sc);}/* copy bytes requested by the client */voidstoreClientCopy(StoreEntry * e,    off_t seen_offset,    off_t copy_offset,    size_t size,    char *buf,    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),	(int) seen_offset,	(int) copy_offset,	(int) size,	callback,	data);    sc = storeClientListSearch(e->mem_obj, data);    assert(sc != NULL);    assert(sc->callback == NULL);    sc->copy_offset = copy_offset;    sc->seen_offset = seen_offset;    sc->callback = callback;    sc->copy_buf = buf;    sc->copy_size = size;    sc->copy_offset = copy_offset;    storeClientCopy2(e, sc);}/* * This function is used below to decide if we have any more data to * send to the client.  If the store_status is STORE_PENDING, then we * do have more data to send.  If its STORE_OK, then * we continue checking.  If the object length is negative, then we * don't know the real length and must open the swap file to find out. * If the length is >= 0, then we compare it to the requested copy * offset. */static intstoreClientNoMoreToSend(StoreEntry * e, store_client * sc){    ssize_t len;    if (e->store_status == STORE_PENDING)	return 0;    if ((len = objectLen(e)) < 0)	return 0;    if (sc->copy_offset < len)	return 0;    return 1;}static voidstoreClientCopy2(StoreEntry * e, store_client * sc){    STCB *callback = sc->callback;    MemObject *mem = e->mem_obj;    size_t sz;    if (sc->flags.copy_event_pending)	return;    if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {	debug(20, 5) ("storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set\n");	return;    }    if (sc->flags.store_copying) {	sc->flags.copy_event_pending = 1;	debug(20, 3) ("storeClientCopy2: Queueing storeClientCopyEvent()\n");	eventAdd("storeClientCopyEvent", storeClientCopyEvent, sc, 0.0, 0);	return;    }    cbdataLock(sc);		/* ick, prevent sc from getting freed */    sc->flags.store_copying = 1;    debug(20, 3) ("storeClientCopy2: %s\n", storeKeyText(e->key));    assert(callback != NULL);    /*     * We used to check for ENTRY_ABORTED here.  But there were some     * problems.  For example, we might have a slow client (or two) and     * the server-side is reading far ahead and swapping to disk.  Even     * if the server-side aborts, we want to give the client(s)     * everything we got before the abort condition occurred.     */    if (storeClientNoMoreToSend(e, sc)) {	/* There is no more to send! */#if USE_ASYNC_IO	if (sc->flags.disk_io_pending) {	    if (sc->swapin_fd >= 0)		aioCancel(sc->swapin_fd, NULL);	    else		aioCancel(-1, sc);	}#endif	sc->flags.disk_io_pending = 0;	sc->callback = NULL;	callback(sc->callback_data, sc->copy_buf, 0);    } else if (e->store_status == STORE_PENDING && sc->seen_offset >= mem->inmem_hi) {	/* client has already seen this, wait for more */	debug(20, 3) ("storeClientCopy2: Waiting for more\n");    } else if (sc->copy_offset >= mem->inmem_lo && sc->copy_offset < mem->inmem_hi) {	/* What the client wants is in memory */	debug(20, 3) ("storeClientCopy2: Copying from memory\n");	sz = stmemCopy(&mem->data_hdr, sc->copy_offset, sc->copy_buf, sc->copy_size);#if USE_ASYNC_IO	if (sc->flags.disk_io_pending) {	    if (sc->swapin_fd >= 0)		aioCancel(sc->swapin_fd, NULL);	    else		aioCancel(-1, sc);	}#endif	sc->flags.disk_io_pending = 0;	sc->callback = NULL;	callback(sc->callback_data, sc->copy_buf, sz);    } else if (sc->swapin_fd < 0) {	debug(20, 3) ("storeClientCopy2: Need to open swap in file\n");	assert(sc->type == STORE_DISK_CLIENT);	/* gotta open the swapin file */	if (storeTooManyDiskFilesOpen()) {	    /* yuck -- this causes a TCP_SWAPFAIL_MISS on the client side */	    sc->callback = NULL;	    callback(sc->callback_data, sc->copy_buf, -1);	} else if (!sc->flags.disk_io_pending) {	    sc->flags.disk_io_pending = 1;	    storeSwapInStart(e, storeClientFileOpened, sc);	} else {	    debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n");	}    } else {	debug(20, 3) ("storeClientCopy: reading from disk FD %d\n",	    sc->swapin_fd);	assert(sc->type == STORE_DISK_CLIENT);	if (!sc->flags.disk_io_pending) {	    storeClientFileRead(sc);	} else {	    debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n");	}    }    sc->flags.store_copying = 0;    cbdataUnlock(sc);		/* ick, allow sc to be freed */}static voidstoreClientFileOpened(int fd, void *data){    store_client *sc = data;    STCB *callback = sc->callback;    if (fd < 0) {	debug(20, 3) ("storeClientFileOpened: failed\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -