]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/AIO/AIODiskIOStrategy.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DiskIO / AIO / AIODiskIOStrategy.cc
CommitLineData
b9ae18aa 1
2/*
b9ae18aa 3 * SQUID Web Proxy Cache http://www.squid-cache.org/
4 * ----------------------------------------------------------
5 *
6 * Squid is the result of efforts by numerous individuals from
7 * the Internet community; see the CONTRIBUTORS file for full
8 * details. Many organizations have provided support for Squid's
9 * development; see the SPONSORS file for full details. Squid is
10 * Copyrighted (C) 2001 by the Regents of the University of
11 * California; see the COPYRIGHT file for full details. Squid
12 * incorporates software developed and/or copyrighted by other
13 * sources; see the CREDITS file for full details.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
26ac0430 19 *
b9ae18aa 20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
26ac0430 24 *
b9ae18aa 25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
28 *
29 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
30 */
31/*
32 * Author: Adrian Chadd <adrian@squid-cache.org>
33 *
34 * These routines are simple plugin replacements for the file_* routines
35 * in disk.c . They back-end into the POSIX AIO routines to provide
36 * a nice and simple async IO framework for COSS.
37 *
38 * AIO is suitable for COSS - the only sync operations that the standard
39 * supports are read/write, and since COSS works on a single file
40 * per storedir it should work just fine.
41 */
42
582c2af2 43#include "squid.h"
b9ae18aa 44#include "AIODiskFile.h"
602d9612 45#include "AIODiskIOStrategy.h"
b9ae18aa 46#include "DiskIO/IORequestor.h"
47#include "DiskIO/ReadRequest.h"
48#include "DiskIO/WriteRequest.h"
49
e19994df
TH
50AIODiskIOStrategy::AIODiskIOStrategy() :
51 fd(-1)
b9ae18aa 52{
e19994df 53 aq.aq_state = AQ_STATE_NONE;
b9ae18aa 54 aq.aq_numpending = 0;
e19994df 55 memset(&aq.aq_queue, 0, sizeof(aq.aq_queue));
b9ae18aa 56}
57
58AIODiskIOStrategy::~AIODiskIOStrategy()
59{
60 assert(aq.aq_state == AQ_STATE_SETUP ||
61 aq.aq_numpending == 0);
62
63 sync();
64 aq.aq_state = AQ_STATE_NONE;
65}
66
67bool
68AIODiskIOStrategy::shedLoad()
69{
70 return false;
71}
72
73int
74AIODiskIOStrategy::load()
75{
76 return aq.aq_numpending * 1000 / MAX_ASYNCOP;
77}
78
79RefCount<DiskFile>
80AIODiskIOStrategy::newFile (char const *path)
81{
82 if (shedLoad()) {
83 return NULL;
84 }
85
86 return new AIODiskFile (path, this);
87}
88
89void
90AIODiskIOStrategy::sync()
91{
92 assert(aq.aq_state == AQ_STATE_SETUP);
93
94 /*
95 * Keep calling callback to complete ops until the queue is empty
96 * We can't quit when callback returns 0 - some calls may not
97 * return any completed pending events, but they're still pending!
98 */
99
100 while (aq.aq_numpending)
101 callback();
102}
103
c521ad17
DK
104bool
105AIODiskIOStrategy::unlinkdUseful() const
106{
107 return false;
108}
109
b9ae18aa 110void
111AIODiskIOStrategy::unlinkFile (char const *)
112{}
113
114/*
115 * Note: we grab the state and free the state before calling the callback
116 * because this allows us to cut down the amount of time it'll take
117 * to find a free slot (since if we call the callback first, we're going
118 * to probably be allocated the slot _after_ this one..)
119 *
120 * I'll make it much more optimal later.
121 */
122int
123AIODiskIOStrategy::callback()
124{
125 return 0;
126 int i;
127 int completed = 0;
128 int retval, reterr;
129 FREE *freefunc;
130 void *cbdata;
131 int callback_valid;
132 void *buf;
b9ae18aa 133 async_queue_entry_t *aqe;
134 async_queue_entry_type_t type;
135
136 assert(aq.aq_state == AQ_STATE_SETUP);
137
138 /* Loop through all slots */
139
cb4185f1 140 for (i = 0; i < MAX_ASYNCOP; ++i) {
b9ae18aa 141 if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_USED) {
142 aqe = &aq.aq_queue[i];
143 /* Active, get status */
144 reterr = aio_error(&aqe->aq_e_aiocb);
145
146 if (reterr < 0) {
147 fatal("aio_error returned an error!\n");
148 }
149
150 if (reterr != EINPROGRESS) {
151 /* Get the return code */
152 retval = aio_return(&aqe->aq_e_aiocb);
153
154 /* Get the callback parameters */
155 freefunc = aqe->aq_e_free;
156 buf = aqe->aq_e_buf;
b9ae18aa 157 type = aqe->aq_e_type;
158 callback_valid = cbdataReferenceValidDone(aqe->aq_e_callback_data, &cbdata);
159 AIODiskFile * theFile = NULL;
160 void *theFileVoid = NULL;
8abf232c 161 void *theTmpFile = aqe->theFile;
162 bool fileOk = cbdataReferenceValidDone(theTmpFile, &theFileVoid);
b9ae18aa 163
164 if (fileOk) {
165 theFile = static_cast<AIODiskFile *>(theFileVoid);
166 }
167
168 /* Free slot */
04830959 169 memset(aqe, 0, sizeof(async_queue_entry_t));
b9ae18aa 170
171 aqe->aq_e_state = AQ_ENTRY_FREE;
172
173 --aq.aq_numpending;
174
175 /* Callback */
176
177 if (callback_valid) {
178 assert (fileOk);
179
180 if (type == AQ_ENTRY_READ)
181 theFile->ioRequestor->readCompleted((const char *)buf, retval, reterr, static_cast<ReadRequest *>(cbdata));
182
183 if (type == AQ_ENTRY_WRITE)
184 theFile->ioRequestor->writeCompleted(reterr,retval, static_cast<WriteRequest *>(cbdata));
185 }
186
187 if (type == AQ_ENTRY_WRITE && freefunc)
188 freefunc(buf);
189 }
190 }
191 }
192
193 return completed;
194}
195
196void
197AIODiskIOStrategy::init()
198{
199 /* Make sure the queue isn't setup */
200 assert(aq.aq_state == AQ_STATE_NONE);
201
202 /* Loop through, blanking the queue entries */
203
204 /* Done */
205 aq.aq_state = AQ_STATE_SETUP;
206}
207
208void
209AIODiskIOStrategy::statfs(StoreEntry & sentry)const
26ac0430 210{}
b9ae18aa 211
212ConfigOption *
213AIODiskIOStrategy::getOptionTree() const
214{
215 return NULL;
216}
217
218/*
219 * find a free aio slot.
220 * Return the index, or -1 if we can't find one.
221 */
222int
223AIODiskIOStrategy::findSlot()
224{
225 /* Later we should use something a little more .. efficient :) */
226
cb4185f1 227 for (int i = 0; i < MAX_ASYNCOP; ++i) {
b9ae18aa 228 if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_FREE)
229 /* Found! */
230 return i;
231 }
232
233 /* found nothing */
234 return -1;
235}