Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: net/base/file_stream_posix.cc

Issue 112090: Avoiding IO completion callback during the closing (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/base/file_stream_unittest.cc » ('j') | net/base/file_stream_win.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | net/base/file_stream_unittest.cc » ('j') | net/base/file_stream_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698