]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/Blocking/BlockingFile.cc
Cleanup: zap CVS Id tags
[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
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 file_read(fd, aRequest->buf, aRequest->len, aRequest->offset, ReadDone, this);
150 }
151
152 void
153 BlockingFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
154 {
155 BlockingFile *myFile = static_cast<BlockingFile *>(my_data);
156 assert (myFile);
157 myFile->readDone (fd, buf, len, errflag);
158 }
159
160 void
161 BlockingFile::write(WriteRequest *aRequest)
162 {
163 debugs(79, 3, "storeUfsWrite: FD " << fd);
164 writeRequest = aRequest;
165 file_write(fd,
166 aRequest->offset,
167 (char *)aRequest->buf,
168 aRequest->len,
169 WriteDone,
170 this,
171 aRequest->free_func);
172 }
173
174 bool
175 BlockingFile::ioInProgress() const
176 {
177 /** \retval false IO is never pending with UFS */
178 return false;
179 }
180
181 /* === STATIC =========================================================== */
182
183 void
184 BlockingFile::readDone(int rvfd, const char *buf, int len, int errflag)
185 {
186 debugs(79, 3, "BlockingFile::readDone: FD " << rvfd);
187 assert (fd == rvfd);
188
189 ssize_t rlen;
190
191 if (errflag) {
192 debugs(79, 3, "BlockingFile::readDone: got failure (" << errflag << ")");
193 rlen = -1;
194 } else {
195 rlen = (ssize_t) len;
196 }
197
198 if (errflag == DISK_EOF)
199 errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
200
201 ReadRequest::Pointer result = readRequest;
202
203 readRequest = NULL;
204
205 ioRequestor->readCompleted(buf, rlen, errflag, result);
206 }
207
208 void
209 BlockingFile::WriteDone (int fd, int errflag, size_t len, void *me)
210 {
211 BlockingFile *aFile = static_cast<BlockingFile *>(me);
212 aFile->writeDone (fd, errflag, len);
213 }
214
215 void
216 BlockingFile::writeDone(int rvfd, int errflag, size_t len)
217 {
218 assert (rvfd == fd);
219 debugs(79, 3, "storeUfsWriteDone: FD " << fd << ", len " << len);
220
221 WriteRequest::Pointer result = writeRequest;
222 writeRequest = NULL;
223
224 if (errflag) {
225 debugs(79, 0, "storeUfsWriteDone: got failure (" << errflag << ")");
226 doClose();
227 ioRequestor->writeCompleted (DISK_ERROR,0, result);
228 return;
229 }
230
231 ioRequestor->writeCompleted(DISK_OK, len, result);
232 }
233