1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/disk_cache/in_flight_io.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace disk_cache { 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBackgroundIO::BackgroundIO(InFlightIO* controller) 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : controller_(controller), result_(-1), io_completed_(true, false) { 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Runs on the primary thread. 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackgroundIO::OnIOSignalled() { 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (controller_) 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->InvokeCallback(this, false); 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackgroundIO::Cancel() { 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(controller_); 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_ = NULL; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBackgroundIO::~BackgroundIO() {} 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Runs on the background thread. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackgroundIO::NotifyController() { 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_->OnIOComplete(this); 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// --------------------------------------------------------------------------- 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickInFlightIO::InFlightIO() 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : callback_thread_(base::MessageLoopProxy::CreateForCurrentThread()), 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick running_(false), single_thread_(false) { 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickInFlightIO::~InFlightIO() { 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InFlightIO::WaitForPendingIO() { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (!io_list_.empty()) { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Block the current thread until all pending IO completes. 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IOList::iterator it = io_list_.begin(); 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InvokeCallback(*it, true); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Runs on a background thread. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InFlightIO::OnIOComplete(BackgroundIO* operation) { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NDEBUG 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (callback_thread_->BelongsToCurrentThread()) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(single_thread_ || !running_); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch single_thread_ = true; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch running_ = true; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch callback_thread_->PostTask(FROM_HERE, 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewRunnableMethod(operation, 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &BackgroundIO::OnIOSignalled)); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch operation->io_completed()->Signal(); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Runs on the primary thread. 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InFlightIO::InvokeCallback(BackgroundIO* operation, bool cancel_task) { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch operation->io_completed()->Wait(); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cancel_task) 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch operation->Cancel(); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure that we remove the operation from the list before invoking the 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // callback (so that a subsequent cancel does not invoke the callback again). 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(io_list_.find(operation) != io_list_.end()); 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch io_list_.erase(make_scoped_refptr(operation)); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnOperationComplete(operation, cancel_task); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Runs on the primary thread. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InFlightIO::OnOperationPosted(BackgroundIO* operation) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(callback_thread_->BelongsToCurrentThread()); 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch io_list_.insert(make_scoped_refptr(operation)); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace disk_cache 88