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 17 WebDataRequest::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 25 WebDataRequest::~WebDataRequest() { 26 if (manager_) { 27 manager_->CancelRequest(handle_); 28 } 29 if (result_.get()) { 30 result_->Destroy(); 31 } 32 } 33 34 WebDataServiceBase::Handle WebDataRequest::GetHandle() const { 35 return handle_; 36 } 37 38 WebDataServiceConsumer* WebDataRequest::GetConsumer() const { 39 return consumer_; 40 } 41 42 base::MessageLoop* WebDataRequest::GetMessageLoop() const { 43 return message_loop_; 44 } 45 46 bool WebDataRequest::IsCancelled() const { 47 base::AutoLock l(cancel_lock_); 48 return cancelled_; 49 } 50 51 void WebDataRequest::Cancel() { 52 base::AutoLock l(cancel_lock_); 53 cancelled_ = true; 54 consumer_ = NULL; 55 manager_ = NULL; 56 } 57 58 void WebDataRequest::OnComplete() { 59 manager_= NULL; 60 } 61 62 void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) { 63 result_ = r.Pass(); 64 } 65 66 scoped_ptr<WDTypedResult> WebDataRequest::GetResult(){ 67 return result_.Pass(); 68 } 69 70 //////////////////////////////////////////////////////////////////////////////// 71 // 72 // WebDataRequestManager implementation. 73 // 74 //////////////////////////////////////////////////////////////////////////////// 75 76 WebDataRequestManager::WebDataRequestManager() 77 : next_request_handle_(1) { 78 } 79 80 WebDataRequestManager::~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 89 void WebDataRequestManager::RegisterRequest(WebDataRequest* request) { 90 base::AutoLock l(pending_lock_); 91 pending_requests_[request->GetHandle()] = request; 92 } 93 94 int WebDataRequestManager::GetNextRequestHandle() { 95 base::AutoLock l(pending_lock_); 96 return ++next_request_handle_; 97 } 98 99 void 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 110 void 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 119 void 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