]>
Commit | Line | Data |
---|---|---|
cd748f27 | 1 | |
2 | /* | |
262a0e14 | 3 | * $Id$ |
cd748f27 | 4 | * |
5 | * DEBUG: section 32 Asynchronous Disk I/O | |
6 | * AUTHOR: Pete Bentley <pete@demon.net> | |
7 | * AUTHOR: Stewart Forster <slf@connect.com.au> | |
8 | * | |
2b6662ba | 9 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
cd748f27 | 10 | * ---------------------------------------------------------- |
11 | * | |
2b6662ba | 12 | * Squid is the result of efforts by numerous individuals from |
13 | * the Internet community; see the CONTRIBUTORS file for full | |
14 | * details. Many organizations have provided support for Squid's | |
15 | * development; see the SPONSORS file for full details. Squid is | |
16 | * Copyrighted (C) 2001 by the Regents of the University of | |
17 | * California; see the COPYRIGHT file for full details. Squid | |
18 | * incorporates software developed and/or copyrighted by other | |
19 | * sources; see the CREDITS file for full details. | |
cd748f27 | 20 | * |
21 | * This program is free software; you can redistribute it and/or modify | |
22 | * it under the terms of the GNU General Public License as published by | |
23 | * the Free Software Foundation; either version 2 of the License, or | |
24 | * (at your option) any later version. | |
26ac0430 | 25 | * |
cd748f27 | 26 | * This program is distributed in the hope that it will be useful, |
27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
29 | * GNU General Public License for more details. | |
26ac0430 | 30 | * |
cd748f27 | 31 | * You should have received a copy of the GNU General Public License |
32 | * along with this program; if not, write to the Free Software | |
33 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
34 | * | |
35 | */ | |
36 | ||
582c2af2 | 37 | #include "squid.h" |
b9ae18aa | 38 | #include "DiskThreads.h" |
e6ccf245 | 39 | #include "Store.h" |
528b2c61 | 40 | #include "fde.h" |
b9ae18aa | 41 | #include "DiskThreadsIOStrategy.h" |
42 | #include "Generic.h" | |
cd748f27 | 43 | |
b9ae18aa | 44 | AIOCounts squidaio_counts; |
cd748f27 | 45 | |
26ac0430 | 46 | typedef struct squidaio_unlinkq_t { |
cd748f27 | 47 | char *path; |
62e76326 | 48 | |
c04d4f40 | 49 | struct squidaio_unlinkq_t *next; |
2fadd50d | 50 | } squidaio_unlinkq_t; |
cd748f27 | 51 | |
b9ae18aa | 52 | dlink_list used_list; |
cd748f27 | 53 | |
54 | void | |
55 | aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data) | |
56 | { | |
c04d4f40 | 57 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 58 | |
b9ae18aa | 59 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 60 | ++squidaio_counts.open_start; |
b9ae18aa | 61 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 62 | ctrlp->fd = -2; |
63 | ctrlp->done_handler = callback; | |
fa80a8ef | 64 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 65 | ctrlp->operation = _AIO_OPEN; |
55f0e6f7 | 66 | ctrlp->result.data = ctrlp; |
c04d4f40 | 67 | squidaio_open(path, oflag, mode, &ctrlp->result); |
55f0e6f7 | 68 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 69 | return; |
70 | } | |
71 | ||
72 | void | |
73 | aioClose(int fd) | |
74 | { | |
c04d4f40 | 75 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 76 | |
b9ae18aa | 77 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 78 | ++squidaio_counts.close_start; |
cd748f27 | 79 | aioCancel(fd); |
b9ae18aa | 80 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 81 | ctrlp->fd = fd; |
82 | ctrlp->done_handler = NULL; | |
83 | ctrlp->done_handler_data = NULL; | |
84 | ctrlp->operation = _AIO_CLOSE; | |
55f0e6f7 | 85 | ctrlp->result.data = ctrlp; |
c04d4f40 | 86 | squidaio_close(fd, &ctrlp->result); |
55f0e6f7 | 87 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 88 | return; |
89 | } | |
90 | ||
91 | void | |
92 | aioCancel(int fd) | |
93 | { | |
211f1d0b | 94 | squidaio_ctrl_t *ctrlp; |
55f0e6f7 | 95 | dlink_node *m, *next; |
cd748f27 | 96 | |
b9ae18aa | 97 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 98 | ++squidaio_counts.cancel; |
62e76326 | 99 | |
55f0e6f7 | 100 | for (m = used_list.head; m; m = next) { |
62e76326 | 101 | next = m->next; |
102 | ctrlp = (squidaio_ctrl_t *)m->data; | |
103 | ||
104 | if (ctrlp->fd != fd) | |
105 | continue; | |
106 | ||
107 | squidaio_cancel(&ctrlp->result); | |
108 | ||
109 | if (ctrlp->done_handler) { | |
110 | AIOCB *callback = ctrlp->done_handler; | |
111 | void *cbdata; | |
112 | ctrlp->done_handler = NULL; | |
e0236918 | 113 | debugs(32, DBG_IMPORTANT, "this be aioCancel. Danger ahead!"); |
62e76326 | 114 | |
115 | if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) | |
116 | callback(fd, cbdata, NULL, -2, -2); | |
117 | ||
118 | /* free data if requested to aioWrite() */ | |
119 | if (ctrlp->free_func) | |
120 | ctrlp->free_func(ctrlp->bufp); | |
121 | ||
122 | /* free temporary read buffer */ | |
123 | if (ctrlp->operation == _AIO_READ) | |
124 | squidaio_xfree(ctrlp->bufp, ctrlp->len); | |
125 | } | |
126 | ||
127 | dlinkDelete(m, &used_list); | |
dc47f531 | 128 | DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->freeOne(ctrlp); |
cd748f27 | 129 | } |
130 | } | |
131 | ||
cd748f27 | 132 | void |
ee139403 | 133 | aioWrite(int fd, off_t offset, char *bufp, size_t len, AIOCB * callback, void *callback_data, FREE * free_func) |
cd748f27 | 134 | { |
c04d4f40 | 135 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 136 | int seekmode; |
137 | ||
b9ae18aa | 138 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 139 | ++squidaio_counts.write_start; |
b9ae18aa | 140 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 141 | ctrlp->fd = fd; |
142 | ctrlp->done_handler = callback; | |
fa80a8ef | 143 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 144 | ctrlp->operation = _AIO_WRITE; |
55f0e6f7 | 145 | ctrlp->bufp = bufp; |
146 | ctrlp->free_func = free_func; | |
62e76326 | 147 | |
cd748f27 | 148 | if (offset >= 0) |
62e76326 | 149 | seekmode = SEEK_SET; |
cd748f27 | 150 | else { |
62e76326 | 151 | seekmode = SEEK_END; |
152 | offset = 0; | |
cd748f27 | 153 | } |
62e76326 | 154 | |
55f0e6f7 | 155 | ctrlp->result.data = ctrlp; |
c04d4f40 | 156 | squidaio_write(fd, bufp, len, offset, seekmode, &ctrlp->result); |
55f0e6f7 | 157 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 158 | } /* aioWrite */ |
159 | ||
cd748f27 | 160 | void |
ee139403 | 161 | aioRead(int fd, off_t offset, size_t len, AIOCB * callback, void *callback_data) |
cd748f27 | 162 | { |
c04d4f40 | 163 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 164 | int seekmode; |
165 | ||
b9ae18aa | 166 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 167 | ++squidaio_counts.read_start; |
b9ae18aa | 168 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 169 | ctrlp->fd = fd; |
170 | ctrlp->done_handler = callback; | |
fa80a8ef | 171 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 172 | ctrlp->operation = _AIO_READ; |
211f1d0b | 173 | ctrlp->len = len; |
d74b7307 | 174 | ctrlp->bufp = (char *)squidaio_xmalloc(len); |
62e76326 | 175 | |
cd748f27 | 176 | if (offset >= 0) |
62e76326 | 177 | seekmode = SEEK_SET; |
cd748f27 | 178 | else { |
62e76326 | 179 | seekmode = SEEK_CUR; |
180 | offset = 0; | |
cd748f27 | 181 | } |
62e76326 | 182 | |
55f0e6f7 | 183 | ctrlp->result.data = ctrlp; |
211f1d0b | 184 | squidaio_read(fd, ctrlp->bufp, len, offset, seekmode, &ctrlp->result); |
55f0e6f7 | 185 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 186 | return; |
187 | } /* aioRead */ | |
188 | ||
189 | void | |
62e76326 | 190 | |
cd748f27 | 191 | aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data) |
192 | { | |
c04d4f40 | 193 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 194 | |
b9ae18aa | 195 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 196 | ++squidaio_counts.stat_start; |
b9ae18aa | 197 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 198 | ctrlp->fd = -2; |
199 | ctrlp->done_handler = callback; | |
fa80a8ef | 200 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 201 | ctrlp->operation = _AIO_STAT; |
55f0e6f7 | 202 | ctrlp->result.data = ctrlp; |
c04d4f40 | 203 | squidaio_stat(path, sb, &ctrlp->result); |
55f0e6f7 | 204 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 205 | return; |
206 | } /* aioStat */ | |
207 | ||
15a47d1d | 208 | void |
efa3acd1 | 209 | aioUnlink(const char *path, AIOCB * callback, void *callback_data) |
15a47d1d | 210 | { |
c04d4f40 | 211 | squidaio_ctrl_t *ctrlp; |
b9ae18aa | 212 | assert(DiskThreadsIOStrategy::Instance.initialised); |
cb4185f1 | 213 | ++squidaio_counts.unlink_start; |
b9ae18aa | 214 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
15a47d1d | 215 | ctrlp->fd = -2; |
216 | ctrlp->done_handler = callback; | |
fa80a8ef | 217 | ctrlp->done_handler_data = cbdataReference(callback_data); |
efa3acd1 | 218 | ctrlp->operation = _AIO_UNLINK; |
55f0e6f7 | 219 | ctrlp->result.data = ctrlp; |
efa3acd1 | 220 | squidaio_unlink(path, &ctrlp->result); |
55f0e6f7 | 221 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
efa3acd1 | 222 | } /* aioUnlink */ |
223 | ||
cd748f27 | 224 | int |
225 | aioQueueSize(void) | |
226 | { | |
b9ae18aa | 227 | return DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->inUseCount(); |
cd748f27 | 228 | } |