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