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 <fcntl.h> | 7 #include <fcntl.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 // operation. | 30 // operation. |
31 BackgroundIO(disk_cache::File* file, const void* buf, size_t buf_len, | 31 BackgroundIO(disk_cache::File* file, const void* buf, size_t buf_len, |
32 size_t offset, disk_cache::FileIOCallback* callback, | 32 size_t offset, disk_cache::FileIOCallback* callback, |
33 InFlightIO* controller) | 33 InFlightIO* controller) |
34 : io_completed_(true, false), callback_(callback), file_(file), buf_(buf), | 34 : io_completed_(true, false), callback_(callback), file_(file), buf_(buf), |
35 buf_len_(buf_len), offset_(offset), controller_(controller), | 35 buf_len_(buf_len), offset_(offset), controller_(controller), |
36 bytes_(0) {} | 36 bytes_(0) {} |
37 | 37 |
38 // Read and Write are the operations that can be performed asynchronously. | 38 // Read and Write are the operations that can be performed asynchronously. |
39 // The actual parameters for the operation are setup in the constructor of | 39 // The actual parameters for the operation are setup in the constructor of |
40 // the object, with the exception of |delete_buffer|, that allows a write | 40 // the object. Both methods should be called from a worker thread, by posting |
41 // without a callback. Both methods should be called from a worker thread, by | 41 // a task to the WorkerPool (they are RunnableMethods). When finished, |
42 // posting a task to the WorkerPool (they are RunnableMethods). When finished, | |
43 // controller->OnIOComplete() is called. | 42 // controller->OnIOComplete() is called. |
44 void Read(); | 43 void Read(); |
45 void Write(bool delete_buffer); | 44 void Write(); |
46 | 45 |
47 // This method signals the controller that this operation is finished, in the | 46 // This method signals the controller that this operation is finished, in the |
48 // original thread (presumably the IO-Thread). In practice, this is a | 47 // original thread (presumably the IO-Thread). In practice, this is a |
49 // RunableMethod that allows cancellation. | 48 // RunableMethod that allows cancellation. |
50 void OnIOSignalled(); | 49 void OnIOSignalled(); |
51 | 50 |
52 // Allows the cancellation of the task to notify the controller (step number 7 | 51 // Allows the cancellation of the task to notify the controller (step number 7 |
53 // in the diagram below). In practice, if the controller waits for the | 52 // in the diagram below). In practice, if the controller waits for the |
54 // operation to finish it doesn't have to wait for the final task to be | 53 // operation to finish it doesn't have to wait for the final task to be |
55 // processed by the message loop so calling this method prevents its delivery. | 54 // processed by the message loop so calling this method prevents its delivery. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 public: | 114 public: |
116 InFlightIO() : callback_thread_(MessageLoop::current()) {} | 115 InFlightIO() : callback_thread_(MessageLoop::current()) {} |
117 ~InFlightIO() {} | 116 ~InFlightIO() {} |
118 | 117 |
119 // These methods start an asynchronous operation. The arguments have the same | 118 // These methods start an asynchronous operation. The arguments have the same |
120 // semantics of the File asynchronous operations, with the exception that the | 119 // semantics of the File asynchronous operations, with the exception that the |
121 // operation never finishes synchronously. | 120 // operation never finishes synchronously. |
122 void PostRead(disk_cache::File* file, void* buf, size_t buf_len, | 121 void PostRead(disk_cache::File* file, void* buf, size_t buf_len, |
123 size_t offset, disk_cache::FileIOCallback* callback); | 122 size_t offset, disk_cache::FileIOCallback* callback); |
124 void PostWrite(disk_cache::File* file, const void* buf, size_t buf_len, | 123 void PostWrite(disk_cache::File* file, const void* buf, size_t buf_len, |
125 size_t offset, disk_cache::FileIOCallback* callback, | 124 size_t offset, disk_cache::FileIOCallback* callback); |
126 bool delete_buffer); | |
127 | 125 |
128 // Blocks the current thread until all IO operations tracked by this object | 126 // Blocks the current thread until all IO operations tracked by this object |
129 // complete. | 127 // complete. |
130 void WaitForPendingIO(); | 128 void WaitForPendingIO(); |
131 | 129 |
132 // Called on a worker thread when |operation| completes. | 130 // Called on a worker thread when |operation| completes. |
133 void OnIOComplete(BackgroundIO* operation); | 131 void OnIOComplete(BackgroundIO* operation); |
134 | 132 |
135 // Invokes the users' completion callback at the end of the IO operation. | 133 // Invokes the users' completion callback at the end of the IO operation. |
136 // |cancel_task| is true if the actual task posted to the thread is still | 134 // |cancel_task| is true if the actual task posted to the thread is still |
(...skipping 23 matching lines...) Expand all Loading... |
160 int BackgroundIO::Result() { | 158 int BackgroundIO::Result() { |
161 return bytes_; | 159 return bytes_; |
162 } | 160 } |
163 | 161 |
164 void BackgroundIO::Cancel() { | 162 void BackgroundIO::Cancel() { |
165 DCHECK(controller_); | 163 DCHECK(controller_); |
166 controller_ = NULL; | 164 controller_ = NULL; |
167 } | 165 } |
168 | 166 |
169 // Runs on a worker thread. | 167 // Runs on a worker thread. |
170 void BackgroundIO::Write(bool delete_buffer) { | 168 void BackgroundIO::Write() { |
171 bool rv = file_->Write(buf_, buf_len_, offset_); | 169 bool rv = file_->Write(buf_, buf_len_, offset_); |
172 if (delete_buffer) { | |
173 // TODO(rvargas): remove or update this code. | |
174 delete[] reinterpret_cast<const char*>(buf_); | |
175 } | |
176 | 170 |
177 bytes_ = rv ? static_cast<int>(buf_len_) : -1; | 171 bytes_ = rv ? static_cast<int>(buf_len_) : -1; |
178 controller_->OnIOComplete(this); | 172 controller_->OnIOComplete(this); |
179 } | 173 } |
180 | 174 |
181 // Runs on the IO thread. | 175 // Runs on the IO thread. |
182 void BackgroundIO::OnIOSignalled() { | 176 void BackgroundIO::OnIOSignalled() { |
183 if (controller_) | 177 if (controller_) |
184 controller_->InvokeCallback(this, false); | 178 controller_->InvokeCallback(this, false); |
185 } | 179 } |
(...skipping 10 matching lines...) Expand all Loading... |
196 if (!callback_thread_) | 190 if (!callback_thread_) |
197 callback_thread_ = MessageLoop::current(); | 191 callback_thread_ = MessageLoop::current(); |
198 | 192 |
199 WorkerPool::PostTask(FROM_HERE, | 193 WorkerPool::PostTask(FROM_HERE, |
200 NewRunnableMethod(operation.get(), &BackgroundIO::Read), | 194 NewRunnableMethod(operation.get(), &BackgroundIO::Read), |
201 true); | 195 true); |
202 } | 196 } |
203 | 197 |
204 void InFlightIO::PostWrite(disk_cache::File* file, const void* buf, | 198 void InFlightIO::PostWrite(disk_cache::File* file, const void* buf, |
205 size_t buf_len, size_t offset, | 199 size_t buf_len, size_t offset, |
206 disk_cache::FileIOCallback* callback, | 200 disk_cache::FileIOCallback* callback) { |
207 bool delete_buffer) { | |
208 scoped_refptr<BackgroundIO> operation = | 201 scoped_refptr<BackgroundIO> operation = |
209 new BackgroundIO(file, buf, buf_len, offset, callback, this); | 202 new BackgroundIO(file, buf, buf_len, offset, callback, this); |
210 io_list_.insert(operation.get()); | 203 io_list_.insert(operation.get()); |
211 file->AddRef(); // Balanced on InvokeCallback() | 204 file->AddRef(); // Balanced on InvokeCallback() |
212 | 205 |
213 if (!callback_thread_) | 206 if (!callback_thread_) |
214 callback_thread_ = MessageLoop::current(); | 207 callback_thread_ = MessageLoop::current(); |
215 | 208 |
216 WorkerPool::PostTask(FROM_HERE, | 209 WorkerPool::PostTask(FROM_HERE, |
217 NewRunnableMethod(operation.get(), &BackgroundIO::Write, | 210 NewRunnableMethod(operation.get(), &BackgroundIO::Write), |
218 delete_buffer), | |
219 true); | 211 true); |
220 } | 212 } |
221 | 213 |
222 void InFlightIO::WaitForPendingIO() { | 214 void InFlightIO::WaitForPendingIO() { |
223 while (!io_list_.empty()) { | 215 while (!io_list_.empty()) { |
224 // Block the current thread until all pending IO completes. | 216 // Block the current thread until all pending IO completes. |
225 IOList::iterator it = io_list_.begin(); | 217 IOList::iterator it = io_list_.begin(); |
226 InvokeCallback(*it, true); | 218 InvokeCallback(*it, true); |
227 } | 219 } |
228 // Unit tests can use different threads. | 220 // Unit tests can use different threads. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 | 327 |
336 bool File::Write(const void* buffer, size_t buffer_len, size_t offset, | 328 bool File::Write(const void* buffer, size_t buffer_len, size_t offset, |
337 FileIOCallback* callback, bool* completed) { | 329 FileIOCallback* callback, bool* completed) { |
338 DCHECK(init_); | 330 DCHECK(init_); |
339 if (!callback) { | 331 if (!callback) { |
340 if (completed) | 332 if (completed) |
341 *completed = true; | 333 *completed = true; |
342 return Write(buffer, buffer_len, offset); | 334 return Write(buffer, buffer_len, offset); |
343 } | 335 } |
344 | 336 |
345 return AsyncWrite(buffer, buffer_len, offset, true, callback, completed); | 337 return AsyncWrite(buffer, buffer_len, offset, callback, completed); |
346 } | |
347 | |
348 bool File::PostWrite(const void* buffer, size_t buffer_len, size_t offset) { | |
349 DCHECK(init_); | |
350 return AsyncWrite(buffer, buffer_len, offset, false, NULL, NULL); | |
351 } | 338 } |
352 | 339 |
353 bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, | 340 bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, |
354 bool notify, FileIOCallback* callback, bool* completed) { | 341 FileIOCallback* callback, bool* completed) { |
355 DCHECK(init_); | 342 DCHECK(init_); |
356 if (buffer_len > ULONG_MAX || offset > ULONG_MAX) | 343 if (buffer_len > ULONG_MAX || offset > ULONG_MAX) |
357 return false; | 344 return false; |
358 | 345 |
359 InFlightIO* io_operations = Singleton<InFlightIO>::get(); | 346 InFlightIO* io_operations = Singleton<InFlightIO>::get(); |
360 io_operations->PostWrite(this, buffer, buffer_len, offset, callback, !notify); | 347 io_operations->PostWrite(this, buffer, buffer_len, offset, callback); |
361 | 348 |
362 if (completed) | 349 if (completed) |
363 *completed = false; | 350 *completed = false; |
364 return true; | 351 return true; |
365 } | 352 } |
366 | 353 |
367 bool File::SetLength(size_t length) { | 354 bool File::SetLength(size_t length) { |
368 DCHECK(init_); | 355 DCHECK(init_); |
369 if (length > ULONG_MAX) | 356 if (length > ULONG_MAX) |
370 return false; | 357 return false; |
371 | 358 |
372 return 0 == ftruncate(platform_file_, length); | 359 return 0 == ftruncate(platform_file_, length); |
373 } | 360 } |
374 | 361 |
375 size_t File::GetLength() { | 362 size_t File::GetLength() { |
376 DCHECK(init_); | 363 DCHECK(init_); |
377 size_t ret = lseek(platform_file_, 0, SEEK_END); | 364 size_t ret = lseek(platform_file_, 0, SEEK_END); |
378 return ret; | 365 return ret; |
379 } | 366 } |
380 | 367 |
381 // Static. | 368 // Static. |
382 void File::WaitForPendingIO(int* num_pending_io) { | 369 void File::WaitForPendingIO(int* num_pending_io) { |
383 // We may be running unit tests so we should allow InFlightIO to reset the | 370 // We may be running unit tests so we should allow InFlightIO to reset the |
384 // message loop. | 371 // message loop. |
385 Singleton<InFlightIO>::get()->WaitForPendingIO(); | 372 Singleton<InFlightIO>::get()->WaitForPendingIO(); |
386 } | 373 } |
387 | 374 |
388 } // namespace disk_cache | 375 } // namespace disk_cache |
OLD | NEW |