OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/disk_cache/file.h" | 5 #include "net/disk_cache/file.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/singleton.h" | 9 #include "base/singleton.h" |
10 #include "net/disk_cache/disk_cache.h" | 10 #include "net/disk_cache/disk_cache.h" |
11 | 11 |
12 namespace { | 12 namespace { |
13 | 13 |
14 // Structure used for asynchronous operations. | 14 // Structure used for asynchronous operations. |
15 struct MyOverlapped { | 15 struct MyOverlapped { |
16 MyOverlapped(disk_cache::File* file, size_t offset, | 16 MyOverlapped(disk_cache::File* file, size_t offset, |
17 disk_cache::FileIOCallback* callback); | 17 disk_cache::FileIOCallback* callback); |
18 ~MyOverlapped(); | 18 ~MyOverlapped() {} |
19 OVERLAPPED* overlapped() { | 19 OVERLAPPED* overlapped() { |
20 return &context_.overlapped; | 20 return &context_.overlapped; |
21 } | 21 } |
22 | 22 |
23 MessageLoopForIO::IOContext context_; | 23 MessageLoopForIO::IOContext context_; |
24 scoped_refptr<disk_cache::File> file_; | 24 scoped_refptr<disk_cache::File> file_; |
25 disk_cache::FileIOCallback* callback_; | 25 disk_cache::FileIOCallback* callback_; |
26 const void* buffer_; | |
27 bool delete_buffer_; // Delete the user buffer at completion. | |
28 }; | 26 }; |
29 | 27 |
30 COMPILE_ASSERT(!offsetof(MyOverlapped, context_), starts_with_overlapped); | 28 COMPILE_ASSERT(!offsetof(MyOverlapped, context_), starts_with_overlapped); |
31 | 29 |
32 // Helper class to handle the IO completion notifications from the message loop. | 30 // Helper class to handle the IO completion notifications from the message loop. |
33 class CompletionHandler : public MessageLoopForIO::IOHandler { | 31 class CompletionHandler : public MessageLoopForIO::IOHandler { |
34 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 32 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
35 DWORD actual_bytes, DWORD error); | 33 DWORD actual_bytes, DWORD error); |
36 }; | 34 }; |
37 | 35 |
(...skipping 15 matching lines...) Expand all Loading... |
53 | 51 |
54 MyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset, | 52 MyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset, |
55 disk_cache::FileIOCallback* callback) { | 53 disk_cache::FileIOCallback* callback) { |
56 memset(this, 0, sizeof(*this)); | 54 memset(this, 0, sizeof(*this)); |
57 context_.handler = Singleton<CompletionHandler>::get(); | 55 context_.handler = Singleton<CompletionHandler>::get(); |
58 context_.overlapped.Offset = static_cast<DWORD>(offset); | 56 context_.overlapped.Offset = static_cast<DWORD>(offset); |
59 file_ = file; | 57 file_ = file; |
60 callback_ = callback; | 58 callback_ = callback; |
61 } | 59 } |
62 | 60 |
63 MyOverlapped::~MyOverlapped() { | |
64 if (delete_buffer_) { | |
65 DCHECK(!callback_); | |
66 // This whole thing could be updated to use IOBuffer, but PostWrite is not | |
67 // used at the moment. TODO(rvargas): remove or update this code. | |
68 delete[] reinterpret_cast<const char*>(buffer_); | |
69 } | |
70 } | |
71 | |
72 } // namespace | 61 } // namespace |
73 | 62 |
74 namespace disk_cache { | 63 namespace disk_cache { |
75 | 64 |
76 File::File(base::PlatformFile file) | 65 File::File(base::PlatformFile file) |
77 : init_(true), mixed_(true), platform_file_(INVALID_HANDLE_VALUE), | 66 : init_(true), mixed_(true), platform_file_(INVALID_HANDLE_VALUE), |
78 sync_platform_file_(file) { | 67 sync_platform_file_(file) { |
79 } | 68 } |
80 | 69 |
81 bool File::Init(const FilePath& name) { | 70 bool File::Init(const FilePath& name) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 189 |
201 bool File::Write(const void* buffer, size_t buffer_len, size_t offset, | 190 bool File::Write(const void* buffer, size_t buffer_len, size_t offset, |
202 FileIOCallback* callback, bool* completed) { | 191 FileIOCallback* callback, bool* completed) { |
203 DCHECK(init_); | 192 DCHECK(init_); |
204 if (!callback) { | 193 if (!callback) { |
205 if (completed) | 194 if (completed) |
206 *completed = true; | 195 *completed = true; |
207 return Write(buffer, buffer_len, offset); | 196 return Write(buffer, buffer_len, offset); |
208 } | 197 } |
209 | 198 |
210 return AsyncWrite(buffer, buffer_len, offset, true, callback, completed); | 199 return AsyncWrite(buffer, buffer_len, offset, callback, completed); |
211 } | |
212 | |
213 bool File::PostWrite(const void* buffer, size_t buffer_len, size_t offset) { | |
214 DCHECK(init_); | |
215 return AsyncWrite(buffer, buffer_len, offset, false, NULL, NULL); | |
216 } | 200 } |
217 | 201 |
218 bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, | 202 bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, |
219 bool notify, FileIOCallback* callback, bool* completed) { | 203 FileIOCallback* callback, bool* completed) { |
220 DCHECK(init_); | 204 DCHECK(init_); |
| 205 DCHECK(callback); |
| 206 DCHECK(completed); |
221 if (buffer_len > ULONG_MAX || offset > ULONG_MAX) | 207 if (buffer_len > ULONG_MAX || offset > ULONG_MAX) |
222 return false; | 208 return false; |
223 | 209 |
224 MyOverlapped* data = new MyOverlapped(this, offset, callback); | 210 MyOverlapped* data = new MyOverlapped(this, offset, callback); |
225 bool dummy_completed; | |
226 if (!callback) { | |
227 DCHECK(!notify); | |
228 data->delete_buffer_ = true; | |
229 data->buffer_ = buffer; | |
230 completed = &dummy_completed; | |
231 } | |
232 | |
233 DWORD size = static_cast<DWORD>(buffer_len); | 211 DWORD size = static_cast<DWORD>(buffer_len); |
234 | 212 |
235 DWORD actual; | 213 DWORD actual; |
236 if (!WriteFile(platform_file_, buffer, size, &actual, data->overlapped())) { | 214 if (!WriteFile(platform_file_, buffer, size, &actual, data->overlapped())) { |
237 *completed = false; | 215 *completed = false; |
238 if (GetLastError() == ERROR_IO_PENDING) | 216 if (GetLastError() == ERROR_IO_PENDING) |
239 return true; | 217 return true; |
240 delete data; | 218 delete data; |
241 return false; | 219 return false; |
242 } | 220 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 void File::WaitForPendingIO(int* num_pending_io) { | 256 void File::WaitForPendingIO(int* num_pending_io) { |
279 while (*num_pending_io) { | 257 while (*num_pending_io) { |
280 // Asynchronous IO operations may be in flight and the completion may end | 258 // Asynchronous IO operations may be in flight and the completion may end |
281 // up calling us back so let's wait for them. | 259 // up calling us back so let's wait for them. |
282 MessageLoopForIO::IOHandler* handler = Singleton<CompletionHandler>::get(); | 260 MessageLoopForIO::IOHandler* handler = Singleton<CompletionHandler>::get(); |
283 MessageLoopForIO::current()->WaitForIOCompletion(100, handler); | 261 MessageLoopForIO::current()->WaitForIOCompletion(100, handler); |
284 } | 262 } |
285 } | 263 } |
286 | 264 |
287 } // namespace disk_cache | 265 } // namespace disk_cache |
OLD | NEW |