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