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