OLD | NEW |
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
3 // LICENSE file. | 3 // LICENSE file. |
4 | 4 |
5 // For 64-bit file access (off_t = off64_t, lseek64, etc). | 5 // For 64-bit file access (off_t = off64_t, lseek64, etc). |
6 #define _FILE_OFFSET_BITS 64 | 6 #define _FILE_OFFSET_BITS 64 |
7 | 7 |
8 #include "net/base/file_stream.h" | 8 #include "net/base/file_stream.h" |
9 | 9 |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 193 |
194 // This is used to synchronize between the AsyncContext destructor (which runs | 194 // This is used to synchronize between the AsyncContext destructor (which runs |
195 // on the IO thread and OnBackgroundIOCompleted() which runs on the WorkerPool | 195 // on the IO thread and OnBackgroundIOCompleted() which runs on the WorkerPool |
196 // thread. | 196 // thread. |
197 base::WaitableEvent background_io_completed_; | 197 base::WaitableEvent background_io_completed_; |
198 | 198 |
199 // These variables are only valid when background_io_completed is signaled. | 199 // These variables are only valid when background_io_completed is signaled. |
200 int result_; | 200 int result_; |
201 CancelableCallbackTask* message_loop_task_; | 201 CancelableCallbackTask* message_loop_task_; |
202 | 202 |
| 203 bool is_closing_; |
| 204 |
203 DISALLOW_COPY_AND_ASSIGN(AsyncContext); | 205 DISALLOW_COPY_AND_ASSIGN(AsyncContext); |
204 }; | 206 }; |
205 | 207 |
206 FileStream::AsyncContext::AsyncContext() | 208 FileStream::AsyncContext::AsyncContext() |
207 : message_loop_(MessageLoopForIO::current()), | 209 : message_loop_(MessageLoopForIO::current()), |
208 callback_(NULL), | 210 callback_(NULL), |
209 background_io_completed_callback_( | 211 background_io_completed_callback_( |
210 this, &AsyncContext::OnBackgroundIOCompleted), | 212 this, &AsyncContext::OnBackgroundIOCompleted), |
211 background_io_completed_(true, false), | 213 background_io_completed_(true, false), |
212 message_loop_task_(NULL) {} | 214 message_loop_task_(NULL), |
| 215 is_closing_(false) {} |
213 | 216 |
214 FileStream::AsyncContext::~AsyncContext() { | 217 FileStream::AsyncContext::~AsyncContext() { |
| 218 is_closing_ = true; |
215 if (callback_) { | 219 if (callback_) { |
216 // If |callback_| is non-NULL, that implies either the worker thread is | 220 // If |callback_| is non-NULL, that implies either the worker thread is |
217 // still running the IO task, or the completion callback is queued up on the | 221 // still running the IO task, or the completion callback is queued up on the |
218 // MessageLoopForIO, but AsyncContext() got deleted before then. | 222 // MessageLoopForIO, but AsyncContext() got deleted before then. |
219 const bool need_to_wait = !background_io_completed_.IsSignaled(); | 223 const bool need_to_wait = !background_io_completed_.IsSignaled(); |
220 base::Time start = base::Time::Now(); | 224 base::Time start = base::Time::Now(); |
221 RunAsynchronousCallback(); | 225 RunAsynchronousCallback(); |
222 if (need_to_wait) { | 226 if (need_to_wait) { |
223 // We want to see if we block the message loop for too long. | 227 // We want to see if we block the message loop for too long. |
224 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", base::Time::Now() - start); | 228 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", base::Time::Now() - start); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 // Wait() here ensures that all modifications from the WorkerPool thread are | 268 // Wait() here ensures that all modifications from the WorkerPool thread are |
265 // now visible. | 269 // now visible. |
266 background_io_completed_.Wait(); | 270 background_io_completed_.Wait(); |
267 | 271 |
268 // Either we're in the MessageLoop's task, in which case Cancel() doesn't do | 272 // Either we're in the MessageLoop's task, in which case Cancel() doesn't do |
269 // anything, or we're in ~AsyncContext(), in which case this prevents the call | 273 // anything, or we're in ~AsyncContext(), in which case this prevents the call |
270 // from happening again. Must do it here after calling Wait(). | 274 // from happening again. Must do it here after calling Wait(). |
271 message_loop_task_->Cancel(); | 275 message_loop_task_->Cancel(); |
272 message_loop_task_ = NULL; | 276 message_loop_task_ = NULL; |
273 | 277 |
| 278 if (is_closing_) { |
| 279 callback_ = NULL; |
| 280 return; |
| 281 } |
| 282 |
274 DCHECK(callback_); | 283 DCHECK(callback_); |
275 CompletionCallback* temp = NULL; | 284 CompletionCallback* temp = NULL; |
276 std::swap(temp, callback_); | 285 std::swap(temp, callback_); |
277 background_io_completed_.Reset(); | 286 background_io_completed_.Reset(); |
278 temp->Run(result_); | 287 temp->Run(result_); |
279 } | 288 } |
280 | 289 |
281 // FileStream ------------------------------------------------------------ | 290 // FileStream ------------------------------------------------------------ |
282 | 291 |
283 FileStream::FileStream() : file_(base::kInvalidPlatformFileValue) { | 292 FileStream::FileStream() : file_(base::kInvalidPlatformFileValue) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 int64 seek_position = Seek(FROM_BEGIN, bytes); | 446 int64 seek_position = Seek(FROM_BEGIN, bytes); |
438 if (seek_position != bytes) | 447 if (seek_position != bytes) |
439 return ERR_UNEXPECTED; | 448 return ERR_UNEXPECTED; |
440 | 449 |
441 // And truncate the file. | 450 // And truncate the file. |
442 int result = ftruncate(file_, bytes); | 451 int result = ftruncate(file_, bytes); |
443 return result == 0 ? seek_position : MapErrorCode(errno); | 452 return result == 0 ? seek_position : MapErrorCode(errno); |
444 } | 453 } |
445 | 454 |
446 } // namespace net | 455 } // namespace net |
OLD | NEW |