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