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

📄 async_io.c

📁 -
💻 C
字号:
/* * $Id: async_io.c,v 1.31 1999/02/01 05:57:05 wessels Exp $ * * DEBUG: section 32    Asynchronous Disk I/O * AUTHOR: Pete Bentley <pete@demon.net> * AUTHOR: Stewart Forster <slf@connect.com.au> * * 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"#if USE_ASYNC_IO#define _AIO_OPEN	0#define _AIO_READ	1#define _AIO_WRITE	2#define _AIO_CLOSE	3#define _AIO_UNLINK	4#define _AIO_OPENDIR	5#define _AIO_STAT	6typedef struct aio_ctrl_t {    struct aio_ctrl_t *next;    int fd;    int operation;    AIOCB *done_handler;    void *done_handler_data;    aio_result_t result;    void *tag;} aio_ctrl_t;struct {    int open;    int close;    int cancel;    int write;    int read;    int stat;    int unlink;    int check_callback;} aio_counts;typedef struct aio_unlinkq_t {    char *path;    struct aio_unlinkq_t *next;} aio_unlinkq_t;static aio_ctrl_t *used_list = NULL;static int initialised = 0;static OBJH aioStats;static MemPool *aio_ctrl_pool;static voidaioInit(){    if (initialised)	return;    aio_ctrl_pool = memPoolCreate("aio_ctrl", sizeof(aio_ctrl_t));    cachemgrRegister("aio_counts", "Async IO Function Counters",	aioStats, 0, 1);    initialised = 1;}voidaioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data, void *tag){    aio_ctrl_t *ctrlp;    int ret;    if (!initialised)	aioInit();    aio_counts.open++;    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = -2;    ctrlp->tag = tag;    ctrlp->done_handler = callback;    ctrlp->done_handler_data = callback_data;    ctrlp->operation = _AIO_OPEN;    if (aio_open(path, oflag, mode, &(ctrlp->result)) < 0) {	ret = open(path, oflag, mode);	if (callback)	    (callback) (ctrlp->fd, callback_data, ret, errno);	memPoolFree(aio_ctrl_pool, ctrlp);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    return;}voidaioClose(int fd){    aio_ctrl_t *ctrlp;    if (!initialised)	aioInit();    aio_counts.close++;    aioCancel(fd, NULL);    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = fd;    ctrlp->tag = NULL;    ctrlp->done_handler = NULL;    ctrlp->done_handler_data = NULL;    ctrlp->operation = _AIO_CLOSE;    if (aio_close(fd, &(ctrlp->result)) < 0) {	close(fd);		/* Can't create thread - do a normal close */	memPoolFree(aio_ctrl_pool, ctrlp);	fd_was_closed(fd);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    return;}voidaioCancel(int fd, void *tag){    aio_ctrl_t *curr;    aio_ctrl_t *prev;    aio_ctrl_t *next;    if (!initialised)	aioInit();    aio_counts.cancel++;    prev = NULL;    curr = used_list;    for (curr = used_list;; curr = next) {	while (curr != NULL) {	    if (curr->fd == fd)		break;	    if (tag != NULL && curr->tag == tag)		break;	    prev = curr;	    curr = curr->next;	}	if (curr == NULL)	    break;	aio_cancel(&(curr->result));	if (curr->done_handler)	    (curr->done_handler) (fd, curr->done_handler_data, -2, -2);	next = curr->next;	if (prev == NULL)	    used_list = next;	else	    prev->next = next;	memPoolFree(aio_ctrl_pool, curr);    }}voidaioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data){    aio_ctrl_t *ctrlp;    int seekmode;    if (!initialised)	aioInit();    aio_counts.write++;    for (ctrlp = used_list; ctrlp != NULL; ctrlp = ctrlp->next)	if (ctrlp->fd == fd)	    break;    if (ctrlp != NULL) {	errno = EWOULDBLOCK;	if (callback)	    (callback) (fd, callback_data, -1, errno);	return;    }    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = fd;    ctrlp->tag = NULL;    ctrlp->done_handler = callback;    ctrlp->done_handler_data = callback_data;    ctrlp->operation = _AIO_WRITE;    if (offset >= 0)	seekmode = SEEK_SET;    else {	seekmode = SEEK_END;	offset = 0;    }    if (aio_write(fd, bufp, len, offset, seekmode, &(ctrlp->result)) < 0) {	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)	    errno = EWOULDBLOCK;	if (callback)	    (callback) (fd, callback_data, -1, errno);	memPoolFree(aio_ctrl_pool, ctrlp);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    return;}				/* aioWrite */voidaioRead(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data){    aio_ctrl_t *ctrlp;    int seekmode;    if (!initialised)	aioInit();    aio_counts.read++;    for (ctrlp = used_list; ctrlp != NULL; ctrlp = ctrlp->next)	if (ctrlp->fd == fd)	    break;    if (ctrlp != NULL) {	errno = EWOULDBLOCK;	if (callback)	    (callback) (fd, callback_data, -1, errno);	return;    }    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = fd;    ctrlp->tag = NULL;    ctrlp->done_handler = callback;    ctrlp->done_handler_data = callback_data;    ctrlp->operation = _AIO_READ;    if (offset >= 0)	seekmode = SEEK_SET;    else {	seekmode = SEEK_CUR;	offset = 0;    }    if (aio_read(fd, bufp, len, offset, seekmode, &(ctrlp->result)) < 0) {	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)	    errno = EWOULDBLOCK;	if (callback)	    (callback) (fd, callback_data, -1, errno);	memPoolFree(aio_ctrl_pool, ctrlp);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    return;}				/* aioRead */voidaioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data, void *tag){    aio_ctrl_t *ctrlp;    if (!initialised)	aioInit();    aio_counts.stat++;    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = -2;    ctrlp->tag = tag;    ctrlp->done_handler = callback;    ctrlp->done_handler_data = callback_data;    ctrlp->operation = _AIO_STAT;    if (aio_stat(path, sb, &(ctrlp->result)) < 0) {	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)	    errno = EWOULDBLOCK;	if (callback)	    (callback) (ctrlp->fd, callback_data, -1, errno);	memPoolFree(aio_ctrl_pool, ctrlp);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    return;}				/* aioStat */voidaioUnlink(const char *pathname, AIOCB * callback, void *callback_data){    aio_ctrl_t *ctrlp;    char *path;    if (!initialised)	aioInit();    aio_counts.unlink++;    ctrlp = memPoolAlloc(aio_ctrl_pool);    ctrlp->fd = -2;    ctrlp->done_handler = callback;    ctrlp->done_handler_data = callback_data;    ctrlp->operation = _AIO_UNLINK;    path = xstrdup(pathname);    if (aio_unlink(path, &(ctrlp->result)) < 0) {	int ret = unlink(path);	(callback) (ctrlp->fd, callback_data, ret, errno);	memPoolFree(aio_ctrl_pool, ctrlp);	xfree(path);	return;    }    ctrlp->next = used_list;    used_list = ctrlp;    xfree(path);}				/* aioUnlink */voidaioCheckCallbacks(){    aio_result_t *resultp;    aio_ctrl_t *ctrlp;    aio_ctrl_t *prev;    if (!initialised)	aioInit();    aio_counts.check_callback++;    for (;;) {	if ((resultp = aio_poll_done()) == NULL)	    break;	prev = NULL;	for (ctrlp = used_list; ctrlp != NULL; prev = ctrlp, ctrlp = ctrlp->next)	    if (&(ctrlp->result) == resultp)		break;	if (ctrlp == NULL)	    continue;	if (prev == NULL)	    used_list = ctrlp->next;	else	    prev->next = ctrlp->next;	if (ctrlp->done_handler)	    (ctrlp->done_handler) (ctrlp->fd, ctrlp->done_handler_data,		ctrlp->result.aio_return, ctrlp->result.aio_errno);	if (ctrlp->operation == _AIO_CLOSE)	    fd_was_closed(ctrlp->fd);	memPoolFree(aio_ctrl_pool, ctrlp);    }}voidaioStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "ASYNC IO Counters:\n");    storeAppendPrintf(sentry, "open\t%d\n", aio_counts.open);    storeAppendPrintf(sentry, "close\t%d\n", aio_counts.close);    storeAppendPrintf(sentry, "cancel\t%d\n", aio_counts.cancel);    storeAppendPrintf(sentry, "write\t%d\n", aio_counts.write);    storeAppendPrintf(sentry, "read\t%d\n", aio_counts.read);    storeAppendPrintf(sentry, "stat\t%d\n", aio_counts.stat);    storeAppendPrintf(sentry, "unlink\t%d\n", aio_counts.unlink);    storeAppendPrintf(sentry, "check_callback\t%d\n", aio_counts.check_callback);}/* Flush all pending I/O */voidaioSync(void){    if (!initialised)	return;			/* nothing to do then */    /* Flush all pending operations */    debug(32, 1) ("aioSync: flushing pending I/O operations\n");    do {	aioCheckCallbacks();    } while (aio_operations_pending());    debug(32, 1) ("aioSync: done\n");}#endif /* USE_ASYNC_IO */

⌨️ 快捷键说明

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