]>
Commit | Line | Data |
---|---|---|
b9ae18aa | 1 | /* |
262a0e14 | 2 | * $Id$ |
b9ae18aa | 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. | |
26ac0430 | 23 | * |
b9ae18aa | 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. | |
26ac0430 | 28 | * |
b9ae18aa | 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 | */ | |
f7f3304a | 35 | #include "squid.h" |
b9ae18aa | 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); | |
63be0a78 | 42 | |
b9ae18aa | 43 | void * |
63be0a78 | 44 | BlockingFile::operator new(size_t sz) |
b9ae18aa | 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 */ | |
b9ae18aa | 50 | return result; |
51 | } | |
52 | ||
53 | void | |
63be0a78 | 54 | BlockingFile::operator delete(void *address) |
b9ae18aa | 55 | { |
56 | BlockingFile *t = static_cast<BlockingFile *>(address); | |
aa625860 | 57 | cbdataFree(t); |
b9ae18aa | 58 | } |
59 | ||
63be0a78 | 60 | BlockingFile::BlockingFile(char const *aPath) : fd (-1), closed (true), error_(false) |
b9ae18aa | 61 | { |
63be0a78 | 62 | assert(aPath); |
bf8fe701 | 63 | debugs(79, 3, "BlockingFile::BlockingFile: " << aPath); |
b9ae18aa | 64 | path_ = xstrdup (aPath); |
65 | } | |
66 | ||
67 | BlockingFile::~BlockingFile() | |
68 | { | |
69 | safe_free (path_); | |
70 | doClose(); | |
71 | } | |
72 | ||
73 | void | |
63be0a78 | 74 | BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback) |
b9ae18aa | 75 | { |
76 | /* Simulate async calls */ | |
77 | fd = file_open(path_ , flags); | |
78 | ioRequestor = callback; | |
79 | ||
80 | if (fd < 0) { | |
bf8fe701 | 81 | debugs(79, 3, "BlockingFile::open: got failure (" << errno << ")"); |
b9ae18aa | 82 | error(true); |
83 | } else { | |
84 | closed = false; | |
cb4185f1 | 85 | ++store_open_disk_fd; |
bf8fe701 | 86 | debugs(79, 3, "BlockingFile::open: opened FD " << fd); |
b9ae18aa | 87 | } |
88 | ||
89 | callback->ioCompletedNotification(); | |
90 | } | |
91 | ||
63be0a78 | 92 | /** |
93 | * Alias for BlockingFile::open(...) | |
94 | \copydoc BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback) | |
95 | */ | |
b9ae18aa | 96 | void |
63be0a78 | 97 | BlockingFile::create(int flags, mode_t mode, RefCount<IORequestor> callback) |
b9ae18aa | 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); | |
cb4185f1 | 109 | --store_open_disk_fd; |
b9ae18aa | 110 | fd = -1; |
111 | } | |
112 | } | |
113 | ||
114 | void | |
63be0a78 | 115 | BlockingFile::close() |
b9ae18aa | 116 | { |
bf8fe701 | 117 | debugs(79, 3, "BlockingFile::close: " << this << " closing for " << ioRequestor.getRaw()); |
b9ae18aa | 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; | |
e2851fe7 | 149 | debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset); |
b9ae18aa | 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 | { | |
e2851fe7 | 164 | debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset); |
b9ae18aa | 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 | |
63be0a78 | 176 | BlockingFile::ioInProgress() const |
b9ae18aa | 177 | { |
63be0a78 | 178 | /** \retval false IO is never pending with UFS */ |
b9ae18aa | 179 | return false; |
180 | } | |
181 | ||
182 | /* === STATIC =========================================================== */ | |
183 | ||
184 | void | |
185 | BlockingFile::readDone(int rvfd, const char *buf, int len, int errflag) | |
186 | { | |
bf8fe701 | 187 | debugs(79, 3, "BlockingFile::readDone: FD " << rvfd); |
b9ae18aa | 188 | assert (fd == rvfd); |
189 | ||
190 | ssize_t rlen; | |
191 | ||
192 | if (errflag) { | |
bf8fe701 | 193 | debugs(79, 3, "BlockingFile::readDone: got failure (" << errflag << ")"); |
b9ae18aa | 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); | |
e557e9df | 220 | debugs(79, 3, HERE << "FD " << fd << ", len " << len); |
b9ae18aa | 221 | |
222 | WriteRequest::Pointer result = writeRequest; | |
223 | writeRequest = NULL; | |
224 | ||
225 | if (errflag) { | |
bf8fe701 | 226 | debugs(79, 0, "storeUfsWriteDone: got failure (" << errflag << ")"); |
b9ae18aa | 227 | doClose(); |
228 | ioRequestor->writeCompleted (DISK_ERROR,0, result); | |
229 | return; | |
230 | } | |
231 | ||
232 | ioRequestor->writeCompleted(DISK_OK, len, result); | |
233 | } | |
234 |