]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/Blocking/BlockingFile.cc
Rock Store implementation merged from the 3p1-rock branch (r9630).
[thirdparty/squid.git] / src / DiskIO / Blocking / BlockingFile.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 47 Store Directory Routines
5 * AUTHOR: Robert Collins
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 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
34 */
35 #include "config.h"
36 #include "BlockingFile.h"
37 #include "DiskIO/IORequestor.h"
38 #include "DiskIO/ReadRequest.h"
39 #include "DiskIO/WriteRequest.h"
40
41 CBDATA_CLASS_INIT(BlockingFile);
42
43 void *
44 BlockingFile::operator new(size_t sz)
45 {
46 CBDATA_INIT_TYPE(BlockingFile);
47 BlockingFile *result = cbdataAlloc(BlockingFile);
48 /* Mark result as being owned - we want the refcounter to do the delete
49 * call */
50 return result;
51 }
52
53 void
54 BlockingFile::operator delete(void *address)
55 {
56 BlockingFile *t = static_cast<BlockingFile *>(address);
57 cbdataFree(t);
58 }
59
60 BlockingFile::BlockingFile(char const *aPath) : fd (-1), closed (true), error_(false)
61 {
62 assert(aPath);
63 debugs(79, 3, "BlockingFile::BlockingFile: " << aPath);
64 path_ = xstrdup (aPath);
65 }
66
67 BlockingFile::~BlockingFile()
68 {
69 safe_free (path_);
70 doClose();
71 }
72
73 void
74 BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
75 {
76 /* Simulate async calls */
77 fd = file_open(path_ , flags);
78 ioRequestor = callback;
79
80 if (fd < 0) {
81 debugs(79, 3, "BlockingFile::open: got failure (" << errno << ")");
82 error(true);
83 } else {
84 closed = false;
85 store_open_disk_fd++;
86 debugs(79, 3, "BlockingFile::open: opened FD " << fd);
87 }
88
89 callback->ioCompletedNotification();
90 }
91
92 /**
93 * Alias for BlockingFile::open(...)
94 \copydoc BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
95 */
96 void
97 BlockingFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
98 {
99 /* We use the same logic path for open */
100 open(flags, mode, callback);
101 }
102
103
104 void BlockingFile::doClose()
105 {
106 if (fd > -1) {
107 closed = true;
108 file_close(fd);
109 store_open_disk_fd--;
110 fd = -1;
111 }
112 }
113
114 void
115 BlockingFile::close()
116 {
117 debugs(79, 3, "BlockingFile::close: " << this << " closing for " << ioRequestor.getRaw());
118 doClose();
119 assert (ioRequestor.getRaw());
120 ioRequestor->closeCompleted();
121 }
122
123 bool
124 BlockingFile::canRead() const
125 {
126 return fd > -1;
127 }
128
129 bool
130 BlockingFile::error() const
131 {
132 if ((fd < 0 && !closed) || error_)
133 return true;
134
135 return false;
136 }
137
138 void BlockingFile::error(bool const &aBool)
139 {
140 error_ = aBool;
141 }
142
143 void
144 BlockingFile::read(ReadRequest *aRequest)
145 {
146 assert (fd > -1);
147 assert (ioRequestor.getRaw());
148 readRequest = aRequest;
149 debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
150 file_read(fd, aRequest->buf, aRequest->len, aRequest->offset, ReadDone, this);
151 }
152
153 void
154 BlockingFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
155 {
156 BlockingFile *myFile = static_cast<BlockingFile *>(my_data);
157 assert (myFile);
158 myFile->readDone (fd, buf, len, errflag);
159 }
160
161 void
162 BlockingFile::write(WriteRequest *aRequest)
163 {
164 debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
165 writeRequest = aRequest;
166 file_write(fd,
167 aRequest->offset,
168 (char *)aRequest->buf,
169 aRequest->len,
170 WriteDone,
171 this,
172 aRequest->free_func);
173 }
174
175 bool
176 BlockingFile::ioInProgress() const
177 {
178 /** \retval false IO is never pending with UFS */
179 return false;
180 }
181
182 /* === STATIC =========================================================== */
183
184 void
185 BlockingFile::readDone(int rvfd, const char *buf, int len, int errflag)
186 {
187 debugs(79, 3, "BlockingFile::readDone: FD " << rvfd);
188 assert (fd == rvfd);
189
190 ssize_t rlen;
191
192 if (errflag) {
193 debugs(79, 3, "BlockingFile::readDone: got failure (" << errflag << ")");
194 rlen = -1;
195 } else {
196 rlen = (ssize_t) len;
197 }
198
199 if (errflag == DISK_EOF)
200 errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
201
202 ReadRequest::Pointer result = readRequest;
203
204 readRequest = NULL;
205
206 ioRequestor->readCompleted(buf, rlen, errflag, result);
207 }
208
209 void
210 BlockingFile::WriteDone (int fd, int errflag, size_t len, void *me)
211 {
212 BlockingFile *aFile = static_cast<BlockingFile *>(me);
213 aFile->writeDone (fd, errflag, len);
214 }
215
216 void
217 BlockingFile::writeDone(int rvfd, int errflag, size_t len)
218 {
219 assert (rvfd == fd);
220 debugs(79,3, HERE << "FD " << fd << ", len " << len);
221
222 WriteRequest::Pointer result = writeRequest;
223 writeRequest = NULL;
224
225 if (errflag) {
226 debugs(79, 0, "storeUfsWriteDone: got failure (" << errflag << ")");
227 doClose();
228 ioRequestor->writeCompleted (DISK_ERROR,0, result);
229 return;
230 }
231
232 ioRequestor->writeCompleted(DISK_OK, len, result);
233 }
234