]>
Commit | Line | Data |
---|---|---|
cd748f27 | 1 | |
2 | /* | |
bf8fe701 | 3 | * $Id: async_io.cc,v 1.4 2007/04/28 22:26:47 hno Exp $ |
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. | |
25 | * | |
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. | |
30 | * | |
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 | ||
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 | |
62e76326 | 46 | typedef struct squidaio_unlinkq_t |
47 | { | |
cd748f27 | 48 | char *path; |
62e76326 | 49 | |
c04d4f40 | 50 | struct squidaio_unlinkq_t *next; |
62e76326 | 51 | } |
52 | ||
53 | squidaio_unlinkq_t; | |
cd748f27 | 54 | |
b9ae18aa | 55 | dlink_list used_list; |
cd748f27 | 56 | |
57 | void | |
58 | aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data) | |
59 | { | |
c04d4f40 | 60 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 61 | |
b9ae18aa | 62 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 63 | squidaio_counts.open_start++; |
b9ae18aa | 64 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 65 | ctrlp->fd = -2; |
66 | ctrlp->done_handler = callback; | |
fa80a8ef | 67 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 68 | ctrlp->operation = _AIO_OPEN; |
55f0e6f7 | 69 | ctrlp->result.data = ctrlp; |
c04d4f40 | 70 | squidaio_open(path, oflag, mode, &ctrlp->result); |
55f0e6f7 | 71 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 72 | return; |
73 | } | |
74 | ||
75 | void | |
76 | aioClose(int fd) | |
77 | { | |
c04d4f40 | 78 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 79 | |
b9ae18aa | 80 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 81 | squidaio_counts.close_start++; |
cd748f27 | 82 | aioCancel(fd); |
b9ae18aa | 83 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 84 | ctrlp->fd = fd; |
85 | ctrlp->done_handler = NULL; | |
86 | ctrlp->done_handler_data = NULL; | |
87 | ctrlp->operation = _AIO_CLOSE; | |
55f0e6f7 | 88 | ctrlp->result.data = ctrlp; |
c04d4f40 | 89 | squidaio_close(fd, &ctrlp->result); |
55f0e6f7 | 90 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 91 | return; |
92 | } | |
93 | ||
94 | void | |
95 | aioCancel(int fd) | |
96 | { | |
211f1d0b | 97 | squidaio_ctrl_t *ctrlp; |
55f0e6f7 | 98 | dlink_node *m, *next; |
cd748f27 | 99 | |
b9ae18aa | 100 | assert(DiskThreadsIOStrategy::Instance.initialised); |
c04d4f40 | 101 | squidaio_counts.cancel++; |
62e76326 | 102 | |
55f0e6f7 | 103 | for (m = used_list.head; m; m = next) { |
62e76326 | 104 | next = m->next; |
105 | ctrlp = (squidaio_ctrl_t *)m->data; | |
106 | ||
107 | if (ctrlp->fd != fd) | |
108 | continue; | |
109 | ||
110 | squidaio_cancel(&ctrlp->result); | |
111 | ||
112 | if (ctrlp->done_handler) { | |
113 | AIOCB *callback = ctrlp->done_handler; | |
114 | void *cbdata; | |
115 | ctrlp->done_handler = NULL; | |
bf8fe701 | 116 | debugs(32, 1, "this be aioCancel. Danger ahead!"); |
62e76326 | 117 | |
118 | if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) | |
119 | callback(fd, cbdata, NULL, -2, -2); | |
120 | ||
121 | /* free data if requested to aioWrite() */ | |
122 | if (ctrlp->free_func) | |
123 | ctrlp->free_func(ctrlp->bufp); | |
124 | ||
125 | /* free temporary read buffer */ | |
126 | if (ctrlp->operation == _AIO_READ) | |
127 | squidaio_xfree(ctrlp->bufp, ctrlp->len); | |
128 | } | |
129 | ||
130 | dlinkDelete(m, &used_list); | |
b9ae18aa | 131 | DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->free(ctrlp); |
cd748f27 | 132 | } |
133 | } | |
134 | ||
135 | ||
136 | void | |
137 | aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data, FREE * free_func) | |
138 | { | |
c04d4f40 | 139 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 140 | int seekmode; |
141 | ||
b9ae18aa | 142 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 143 | squidaio_counts.write_start++; |
b9ae18aa | 144 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 145 | ctrlp->fd = fd; |
146 | ctrlp->done_handler = callback; | |
fa80a8ef | 147 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 148 | ctrlp->operation = _AIO_WRITE; |
55f0e6f7 | 149 | ctrlp->bufp = bufp; |
150 | ctrlp->free_func = free_func; | |
62e76326 | 151 | |
cd748f27 | 152 | if (offset >= 0) |
62e76326 | 153 | seekmode = SEEK_SET; |
cd748f27 | 154 | else { |
62e76326 | 155 | seekmode = SEEK_END; |
156 | offset = 0; | |
cd748f27 | 157 | } |
62e76326 | 158 | |
55f0e6f7 | 159 | ctrlp->result.data = ctrlp; |
c04d4f40 | 160 | squidaio_write(fd, bufp, len, offset, seekmode, &ctrlp->result); |
55f0e6f7 | 161 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 162 | } /* aioWrite */ |
163 | ||
164 | ||
165 | void | |
211f1d0b | 166 | aioRead(int fd, int offset, int len, AIOCB * callback, void *callback_data) |
cd748f27 | 167 | { |
c04d4f40 | 168 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 169 | int seekmode; |
170 | ||
b9ae18aa | 171 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 172 | squidaio_counts.read_start++; |
b9ae18aa | 173 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 174 | ctrlp->fd = fd; |
175 | ctrlp->done_handler = callback; | |
fa80a8ef | 176 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 177 | ctrlp->operation = _AIO_READ; |
211f1d0b | 178 | ctrlp->len = len; |
d74b7307 | 179 | ctrlp->bufp = (char *)squidaio_xmalloc(len); |
62e76326 | 180 | |
cd748f27 | 181 | if (offset >= 0) |
62e76326 | 182 | seekmode = SEEK_SET; |
cd748f27 | 183 | else { |
62e76326 | 184 | seekmode = SEEK_CUR; |
185 | offset = 0; | |
cd748f27 | 186 | } |
62e76326 | 187 | |
55f0e6f7 | 188 | ctrlp->result.data = ctrlp; |
211f1d0b | 189 | squidaio_read(fd, ctrlp->bufp, len, offset, seekmode, &ctrlp->result); |
55f0e6f7 | 190 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 191 | return; |
192 | } /* aioRead */ | |
193 | ||
194 | void | |
62e76326 | 195 | |
cd748f27 | 196 | aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data) |
197 | { | |
c04d4f40 | 198 | squidaio_ctrl_t *ctrlp; |
cd748f27 | 199 | |
b9ae18aa | 200 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 201 | squidaio_counts.stat_start++; |
b9ae18aa | 202 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
cd748f27 | 203 | ctrlp->fd = -2; |
204 | ctrlp->done_handler = callback; | |
fa80a8ef | 205 | ctrlp->done_handler_data = cbdataReference(callback_data); |
cd748f27 | 206 | ctrlp->operation = _AIO_STAT; |
55f0e6f7 | 207 | ctrlp->result.data = ctrlp; |
c04d4f40 | 208 | squidaio_stat(path, sb, &ctrlp->result); |
55f0e6f7 | 209 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
cd748f27 | 210 | return; |
211 | } /* aioStat */ | |
212 | ||
15a47d1d | 213 | void |
efa3acd1 | 214 | aioUnlink(const char *path, AIOCB * callback, void *callback_data) |
15a47d1d | 215 | { |
c04d4f40 | 216 | squidaio_ctrl_t *ctrlp; |
b9ae18aa | 217 | assert(DiskThreadsIOStrategy::Instance.initialised); |
12e137b0 | 218 | squidaio_counts.unlink_start++; |
b9ae18aa | 219 | ctrlp = (squidaio_ctrl_t *)DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->alloc(); |
15a47d1d | 220 | ctrlp->fd = -2; |
221 | ctrlp->done_handler = callback; | |
fa80a8ef | 222 | ctrlp->done_handler_data = cbdataReference(callback_data); |
efa3acd1 | 223 | ctrlp->operation = _AIO_UNLINK; |
55f0e6f7 | 224 | ctrlp->result.data = ctrlp; |
efa3acd1 | 225 | squidaio_unlink(path, &ctrlp->result); |
55f0e6f7 | 226 | dlinkAdd(ctrlp, &ctrlp->node, &used_list); |
efa3acd1 | 227 | } /* aioUnlink */ |
228 | ||
cd748f27 | 229 | int |
230 | aioQueueSize(void) | |
231 | { | |
b9ae18aa | 232 | return DiskThreadsIOStrategy::Instance.squidaio_ctrl_pool->inUseCount(); |
cd748f27 | 233 | } |