1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "components/webdata/common/web_data_request_manager.h" 6 7#include "base/bind.h" 8#include "base/message_loop/message_loop.h" 9#include "base/stl_util.h" 10 11//////////////////////////////////////////////////////////////////////////////// 12// 13// WebDataRequest implementation. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17WebDataRequest::WebDataRequest(WebDataServiceConsumer* consumer, 18 WebDataRequestManager* manager) 19 : manager_(manager), cancelled_(false), consumer_(consumer) { 20 handle_ = manager_->GetNextRequestHandle(); 21 message_loop_ = base::MessageLoop::current(); 22 manager_->RegisterRequest(this); 23} 24 25WebDataRequest::~WebDataRequest() { 26 if (manager_) { 27 manager_->CancelRequest(handle_); 28 } 29 if (result_.get()) { 30 result_->Destroy(); 31 } 32} 33 34WebDataServiceBase::Handle WebDataRequest::GetHandle() const { 35 return handle_; 36} 37 38WebDataServiceConsumer* WebDataRequest::GetConsumer() const { 39 return consumer_; 40} 41 42base::MessageLoop* WebDataRequest::GetMessageLoop() const { 43 return message_loop_; 44} 45 46bool WebDataRequest::IsCancelled() const { 47 base::AutoLock l(cancel_lock_); 48 return cancelled_; 49} 50 51void WebDataRequest::Cancel() { 52 base::AutoLock l(cancel_lock_); 53 cancelled_ = true; 54 consumer_ = NULL; 55 manager_ = NULL; 56} 57 58void WebDataRequest::OnComplete() { 59 manager_= NULL; 60} 61 62void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) { 63 result_ = r.Pass(); 64} 65 66scoped_ptr<WDTypedResult> WebDataRequest::GetResult(){ 67 return result_.Pass(); 68} 69 70//////////////////////////////////////////////////////////////////////////////// 71// 72// WebDataRequestManager implementation. 73// 74//////////////////////////////////////////////////////////////////////////////// 75 76WebDataRequestManager::WebDataRequestManager() 77 : next_request_handle_(1) { 78} 79 80WebDataRequestManager::~WebDataRequestManager() { 81 base::AutoLock l(pending_lock_); 82 for (RequestMap::iterator i = pending_requests_.begin(); 83 i != pending_requests_.end(); ++i) { 84 i->second->Cancel(); 85 } 86 pending_requests_.clear(); 87} 88 89void WebDataRequestManager::RegisterRequest(WebDataRequest* request) { 90 base::AutoLock l(pending_lock_); 91 pending_requests_[request->GetHandle()] = request; 92} 93 94int WebDataRequestManager::GetNextRequestHandle() { 95 base::AutoLock l(pending_lock_); 96 return ++next_request_handle_; 97} 98 99void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) { 100 base::AutoLock l(pending_lock_); 101 RequestMap::iterator i = pending_requests_.find(h); 102 if (i == pending_requests_.end()) { 103 NOTREACHED() << "Canceling a nonexistent web data service request"; 104 return; 105 } 106 i->second->Cancel(); 107 pending_requests_.erase(i); 108} 109 110void WebDataRequestManager::RequestCompleted( 111 scoped_ptr<WebDataRequest> request) { 112 base::MessageLoop* loop = request->GetMessageLoop(); 113 loop->PostTask(FROM_HERE, 114 base::Bind(&WebDataRequestManager::RequestCompletedOnThread, 115 this, 116 base::Passed(&request))); 117} 118 119void WebDataRequestManager::RequestCompletedOnThread( 120 scoped_ptr<WebDataRequest> request) { 121 if (request->IsCancelled()) 122 return; 123 { 124 base::AutoLock l(pending_lock_); 125 RequestMap::iterator i = pending_requests_.find(request->GetHandle()); 126 if (i == pending_requests_.end()) { 127 NOTREACHED() << "Request completed called for an unknown request"; 128 return; 129 } 130 131 // Take ownership of the request object and remove it from the map. 132 pending_requests_.erase(i); 133 } 134 135 // Notify the consumer if needed. 136 if (!request->IsCancelled()) { 137 WebDataServiceConsumer* consumer = request->GetConsumer(); 138 request->OnComplete(); 139 if (consumer) { 140 scoped_ptr<WDTypedResult> r = request->GetResult(); 141 consumer->OnWebDataServiceRequestDone(request->GetHandle(), r.get()); 142 } 143 } 144 145} 146