]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/AIO/AIODiskFile.cc
Author: Francesco Chemolli <kinkie@squid-cache.org>
[thirdparty/squid.git] / src / DiskIO / AIO / AIODiskFile.cc
1 /*
2 * $Id$
3 *
4 * SQUID Web Proxy Cache http://www.squid-cache.org/
5 * ----------------------------------------------------------
6 *
7 * Squid is the result of efforts by numerous individuals from
8 * the Internet community; see the CONTRIBUTORS file for full
9 * details. Many organizations have provided support for Squid's
10 * development; see the SPONSORS file for full details. Squid is
11 * Copyrighted (C) 2001 by the Regents of the University of
12 * California; see the COPYRIGHT file for full details. Squid
13 * incorporates software developed and/or copyrighted by other
14 * sources; see the CREDITS file for full details.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
29 *
30 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
31 */
32
33 /**
34 * Author: Adrian Chadd <adrian@squid-cache.org>
35 *
36 \par
37 * These routines are simple plugin replacements for the file_* routines
38 * in disk.c . They back-end into the POSIX AIO routines to provide
39 * a nice and simple async IO framework for COSS.
40 *
41 \par
42 * AIO is suitable for COSS - the only sync operations that the standard
43 * supports are read/write, and since COSS works on a single file
44 * per storedir it should work just fine.
45 */
46
47 #include "squid.h"
48 #include "AIODiskFile.h"
49 #include "AIODiskIOStrategy.h"
50 #include "DiskIO/IORequestor.h"
51 #include "DiskIO/ReadRequest.h"
52 #include "DiskIO/WriteRequest.h"
53
54 CBDATA_CLASS_INIT(AIODiskFile);
55 void *
56 AIODiskFile::operator new(size_t unused)
57 {
58 CBDATA_INIT_TYPE(AIODiskFile);
59 return cbdataAlloc(AIODiskFile);
60 }
61
62 void
63 AIODiskFile::operator delete(void *address)
64 {
65 cbdataFree(address);
66 }
67
68 AIODiskFile::AIODiskFile(char const *aPath, AIODiskIOStrategy *aStrategy) : fd(-1), closed(true), error_(false)
69 {
70 assert (aPath);
71 path = aPath;
72 strategy = aStrategy;
73 debugs(79, 3, "AIODiskFile::AIODiskFile: " << aPath);
74 }
75
76 AIODiskFile::~AIODiskFile()
77 {}
78
79 void
80 AIODiskFile::error(bool const &aBool)
81 {
82 error_ = aBool;
83 }
84
85 void
86 AIODiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
87 {
88 /* Simulate async calls */
89 #ifdef _SQUID_WIN32_
90 fd = aio_open(path.unsafeBuf(), flags);
91 #else
92
93 fd = file_open(path.unsafeBuf() , flags);
94 #endif
95
96 ioRequestor = callback;
97
98 if (fd < 0) {
99 debugs(79, 3, HERE << ": got failure (" << errno << ")");
100 error(true);
101 } else {
102 closed = false;
103 store_open_disk_fd++;
104 debugs(79, 3, HERE << ": opened FD " << fd);
105 }
106
107 callback->ioCompletedNotification();
108 }
109
110 void
111 AIODiskFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
112 {
113 /* We use the same logic path for open */
114 open(flags, mode, callback);
115 }
116
117 void
118 AIODiskFile::read(ReadRequest *request)
119 {
120 int slot;
121 async_queue_entry_t *qe;
122
123 assert(strategy->aq.aq_state == AQ_STATE_SETUP);
124
125 /* Find a free slot */
126 slot = strategy->findSlot();
127
128 if (slot < 0) {
129 /* No free slot? Callback error, and return */
130 fatal("Aiee! out of aiocb slots! - FIXME and wrap file_read\n");
131 debugs(79, 1, "WARNING: out of aiocb slots!");
132 /* fall back to blocking method */
133 // file_read(fd, request->unsafeBuf, request->len, request->offset, callback, data);
134 return;
135 }
136
137 /* Mark slot as ours */
138 qe = &strategy->aq.aq_queue[slot];
139
140 qe->aq_e_state = AQ_ENTRY_USED;
141
142 qe->aq_e_callback_data = cbdataReference(request);
143
144 qe->theFile = cbdataReference(this);
145
146 qe->aq_e_type = AQ_ENTRY_READ;
147
148 qe->aq_e_free = NULL;
149
150 qe->aq_e_buf = request->buf;
151
152 qe->aq_e_fd = getFD();
153
154 qe->aq_e_aiocb.aio_fildes = getFD();
155
156 qe->aq_e_aiocb.aio_nbytes = request->len;
157
158 qe->aq_e_aiocb.aio_offset = request->offset;
159
160 qe->aq_e_aiocb.aio_buf = request->buf;
161
162 /* Account */
163 strategy->aq.aq_numpending++;
164
165 /* Initiate aio */
166 if (aio_read(&qe->aq_e_aiocb) < 0) {
167 fatalf("Aiee! aio_read() returned error (%d) FIXME and wrap file_read !\n", errno);
168 debugs(79, 1, "WARNING: aio_read() returned error: " << xstrerror());
169 /* fall back to blocking method */
170 // file_read(fd, request->unsafeBuf, request->len, request->offset, callback, data);
171 }
172
173 }
174
175 void
176 AIODiskFile::write(WriteRequest *request)
177 {
178 int slot;
179 async_queue_entry_t *qe;
180
181 assert(strategy->aq.aq_state == AQ_STATE_SETUP);
182
183 /* Find a free slot */
184 slot = strategy->findSlot();
185
186 if (slot < 0) {
187 /* No free slot? Callback error, and return */
188 fatal("Aiee! out of aiocb slots FIXME and wrap file_write !\n");
189 debugs(79, 1, "WARNING: out of aiocb slots!");
190 /* fall back to blocking method */
191 // file_write(fd, offset, unsafeBuf, len, callback, data, freefunc);
192 return;
193 }
194
195 /* Mark slot as ours */
196 qe = &strategy->aq.aq_queue[slot];
197
198 qe->aq_e_state = AQ_ENTRY_USED;
199
200 qe->aq_e_callback_data = cbdataReference(request);
201
202 qe->theFile = cbdataReference(this);
203
204 qe->aq_e_type = AQ_ENTRY_WRITE;
205
206 qe->aq_e_free = request->free_func;
207
208 qe->aq_e_buf = (void *)request->buf;
209
210 qe->aq_e_fd = fd;
211
212 qe->aq_e_aiocb.aio_fildes = fd;
213
214 qe->aq_e_aiocb.aio_nbytes = request->len;
215
216 qe->aq_e_aiocb.aio_offset = request->offset;
217
218 qe->aq_e_aiocb.aio_buf = (void *)request->buf;
219
220 /* Account */
221 ++strategy->aq.aq_numpending;
222
223 /* Initiate aio */
224 if (aio_write(&qe->aq_e_aiocb) < 0) {
225 fatalf("Aiee! aio_write() returned error (%d) FIXME and wrap file_write !\n", errno);
226 debugs(79, 1, "WARNING: aio_write() returned error: " << xstrerror());
227 /* fall back to blocking method */
228 // file_write(fd, offset, unsafeBuf, len, callback, data, freefunc);
229 }
230 }
231
232 void
233 AIODiskFile::close ()
234 {
235 assert (!closed);
236 #ifdef _SQUID_WIN32_
237
238 aio_close(fd);
239 #else
240
241 file_close(fd);
242 #endif
243
244 fd = -1;
245 closed = true;
246 assert (ioRequestor != NULL);
247 ioRequestor->closeCompleted();
248 }
249
250 bool
251 AIODiskFile::canRead() const
252 {
253 return true;
254 }
255
256 bool
257 AIODiskFile::canWrite() const
258 {
259 return true;
260 }
261
262 int
263 AIODiskFile::getFD() const
264 {
265 return fd;
266 }
267
268 bool
269 AIODiskFile::error() const
270 {
271 return error_;
272 }
273
274 bool
275 AIODiskFile::ioInProgress() const
276 {
277 return false;
278 }