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