]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc
Fix some issues revealed by Coverty Scan, improve documentation of parseHttpRequest
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsIOStrategy.cc
CommitLineData
b9ae18aa 1
2/*
b9ae18aa 3 * DEBUG: section 79 Squid-side Disk I/O functions.
4 * AUTHOR: Robert Collins
5 *
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
8 *
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
26ac0430 22 *
b9ae18aa 23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
26ac0430 27 *
b9ae18aa 28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
31 *
32 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
33 */
34
582c2af2 35#include "squid.h"
b9ae18aa 36
b9ae18aa 37#include "DiskThreadsDiskFile.h"
8822ebee
AR
38#include "DiskThreadsIOStrategy.h"
39#include "fde.h"
40#include "mgr/Registration.h"
4d5904f7 41#include "SquidConfig.h"
e4f1fdae 42#include "StatCounters.h"
b9ae18aa 43#include "Store.h"
8822ebee 44
b9ae18aa 45void
46DiskThreadsIOStrategy::init(void)
47{
48 if (initialised)
49 return;
50
04eb0689 51 squidaio_ctrl_pool = memPoolCreate("aio_ctrl", sizeof(squidaio_ctrl_t));
b9ae18aa 52
b9ae18aa 53 initialised = true;
e65c313f 54
55 /*
56 * We'd like to call squidaio_init() here, but the configuration
57 * hasn't been parsed yet and we don't know how many cache_dirs
58 * there are, which means we don't know how many threads to start.
59 */
6fdc2d18 60
26ac0430 61 registerWithCacheManager();
b9ae18aa 62}
63
62ee09ca 64void
15fab853 65DiskThreadsIOStrategy::registerWithCacheManager(void)
62ee09ca 66{
8822ebee 67 Mgr::RegisterAction("squidaio_counts", "Async IO Function Counters",
d9fc6862 68 aioStats, 0, 1);
62ee09ca 69}
70
b9ae18aa 71void
72DiskThreadsIOStrategy::done(void)
73{
74 if (!initialised)
75 return;
76
d06925a4 77 squidaio_shutdown();
78
b9ae18aa 79 delete squidaio_ctrl_pool;
80
81 squidaio_ctrl_pool = NULL;
82
83 initialised = false;
84}
85
86int
87DiskThreadsIOStrategy::callback()
88{
89 squidaio_result_t *resultp;
90 squidaio_ctrl_t *ctrlp;
91 int retval = 0;
92
93 assert(initialised);
cb4185f1 94 ++squidaio_counts.check_callback;
b9ae18aa 95
96 for (;;) {
97 if ((resultp = squidaio_poll_done()) == NULL)
98 break;
99
100 ctrlp = (squidaio_ctrl_t *) resultp->data;
101
102 switch (resultp->result_type) {
103
104 case _AIO_OP_NONE:
105
b9ae18aa 106 case _AIO_OP_OPENDIR:
107 break;
108
109 case _AIO_OP_OPEN:
110 ++squidaio_counts.open_finish;
111 break;
112
113 case _AIO_OP_READ:
114 ++squidaio_counts.read_finish;
115 break;
116
117 case _AIO_OP_WRITE:
118 ++squidaio_counts.write_finish;
119 break;
120
121 case _AIO_OP_CLOSE:
122 ++squidaio_counts.close_finish;
123 break;
124
125 case _AIO_OP_UNLINK:
126 ++squidaio_counts.unlink_finish;
127 break;
128
129 case _AIO_OP_STAT:
130 ++squidaio_counts.stat_finish;
131 break;
132 }
133
134 if (ctrlp == NULL)
135 continue; /* XXX Should not happen */
136
137 dlinkDelete(&ctrlp->node, &used_list);
138
139 if (ctrlp->done_handler) {
350e2aec 140 AIOCB *done_callback = ctrlp->done_handler;
b9ae18aa 141 void *cbdata;
142 ctrlp->done_handler = NULL;
143
144 if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata)) {
145 retval = 1; /* Return that we've actually done some work */
350e2aec 146 done_callback(ctrlp->fd, cbdata, ctrlp->bufp,
0cc4a8bc 147 ctrlp->result.aio_return, ctrlp->result.aio_errno);
b9ae18aa 148 } else {
149 if (ctrlp->operation == _AIO_OPEN) {
150 /* The open operation was aborted.. */
151 int fd = ctrlp->result.aio_return;
152
153 if (fd >= 0)
154 aioClose(fd);
155 }
156 }
157 }
158
159 /* free data if requested to aioWrite() */
160 if (ctrlp->free_func)
161 ctrlp->free_func(ctrlp->bufp);
162
163 /* free temporary read buffer */
164 if (ctrlp->operation == _AIO_READ)
165 squidaio_xfree(ctrlp->bufp, ctrlp->len);
166
dc47f531 167 squidaio_ctrl_pool->freeOne(ctrlp);
b9ae18aa 168 }
169
170 return retval;
171}
172
173/* Flush all pending I/O */
174void
175DiskThreadsIOStrategy::sync()
176{
177 if (!initialised)
178 return; /* nothing to do then */
179
180 /* Flush all pending operations */
709873c3 181 debugs(32, 2, "aioSync: flushing pending I/O operations");
b9ae18aa 182
183 do {
184 callback();
185 } while (squidaio_sync());
186
709873c3 187 debugs(32, 2, "aioSync: done");
b9ae18aa 188}
189
190DiskThreadsIOStrategy::DiskThreadsIOStrategy() : initialised (false) {}
191
192void
193DiskThreadsIOStrategy::aioStats(StoreEntry * sentry)
194{
195 storeAppendPrintf(sentry, "ASYNC IO Counters:\n");
196 storeAppendPrintf(sentry, "Operation\t# Requests\tNumber serviced\n");
197 storeAppendPrintf(sentry, "open\t%d\t%d\n", squidaio_counts.open_start, squidaio_counts.open_finish);
198 storeAppendPrintf(sentry, "close\t%d\t%d\n", squidaio_counts.close_start, squidaio_counts.close_finish);
199 storeAppendPrintf(sentry, "cancel\t%d\t-\n", squidaio_counts.cancel);
200 storeAppendPrintf(sentry, "write\t%d\t%d\n", squidaio_counts.write_start, squidaio_counts.write_finish);
201 storeAppendPrintf(sentry, "read\t%d\t%d\n", squidaio_counts.read_start, squidaio_counts.read_finish);
202 storeAppendPrintf(sentry, "stat\t%d\t%d\n", squidaio_counts.stat_start, squidaio_counts.stat_finish);
203 storeAppendPrintf(sentry, "unlink\t%d\t%d\n", squidaio_counts.unlink_start, squidaio_counts.unlink_finish);
204 storeAppendPrintf(sentry, "check_callback\t%d\t-\n", squidaio_counts.check_callback);
205 storeAppendPrintf(sentry, "queue\t%d\t-\n", squidaio_get_queue_len());
b0465494 206 squidaio_stats(sentry);
b9ae18aa 207}
208
b9ae18aa 209DiskThreadsIOStrategy DiskThreadsIOStrategy::Instance;
210bool
211DiskThreadsIOStrategy::shedLoad()
212{
213 /*
214 * we should detect some 'too many files open' condition and return
215 * NULL here.
216 */
217#ifdef MAGIC2
218
219 if (aioQueueSize() > MAGIC2)
220 return true;
221
222#endif
223
224 return false;
225}
226
227int
228DiskThreadsIOStrategy::load()
229{
230 int loadav;
231 int ql;
232
233 ql = aioQueueSize();
234
235 if (ql == 0)
236 loadav = 0;
237
238 loadav = ql * 1000 / MAGIC1;
239
bf8fe701 240 debugs(47, 9, "DiskThreadsIOStrategy::load: load=" << loadav);
b9ae18aa 241
242 return loadav;
243}
244
245DiskFile::Pointer
246DiskThreadsIOStrategy::newFile (char const *path)
247{
248 if (shedLoad()) {
249 return NULL;
250 }
251
252 return new DiskThreadsDiskFile (path, this);
253}
254
c521ad17
DK
255bool
256DiskThreadsIOStrategy::unlinkdUseful() const
257{
258 return false;
259}
260
b9ae18aa 261void
262DiskThreadsIOStrategy::unlinkFile(char const *path)
263{
e4f1fdae 264 ++statCounter.syscalls.disk.unlinks;
b9ae18aa 265 aioUnlink(path, NULL, NULL);
b9ae18aa 266}