Home | History | Annotate | Download | only in common
      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