Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: chrome/browser/webdata/web_data_request_manager.cc

Issue 11862010: Fix WebDataRequest ownership gap (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/webdata/web_data_request_manager.h" 5 #include "chrome/browser/webdata/web_data_request_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "chrome/browser/autofill/autofill_profile.h"
11 #include "chrome/browser/autofill/credit_card.h"
12 #include "chrome/browser/webdata/web_data_service.h" 10 #include "chrome/browser/webdata/web_data_service.h"
13 11
14 //////////////////////////////////////////////////////////////////////////////// 12 ////////////////////////////////////////////////////////////////////////////////
15 // 13 //
16 // WebDataRequest implementation. 14 // WebDataRequest implementation.
17 // 15 //
18 //////////////////////////////////////////////////////////////////////////////// 16 ////////////////////////////////////////////////////////////////////////////////
19 17
20 WebDataRequest::WebDataRequest(WebDataService* service, 18 WebDataRequest::WebDataRequest(WebDataService* service,
21 WebDataServiceConsumer* consumer, 19 WebDataServiceConsumer* consumer,
22 WebDataRequestManager* manager) 20 WebDataRequestManager* manager)
23 : service_(service), 21 : service_(service),
22 manager_(manager),
24 cancelled_(false), 23 cancelled_(false),
25 consumer_(consumer), 24 consumer_(consumer),
26 result_(NULL) { 25 result_(NULL) {
27 handle_ = manager->GetNextRequestHandle(); 26 handle_ = manager_->GetNextRequestHandle();
28 message_loop_ = MessageLoop::current(); 27 message_loop_ = MessageLoop::current();
29 manager->RegisterRequest(this); 28 manager_->RegisterRequest(this);
30 } 29 }
31 30
32 WebDataRequest::~WebDataRequest() { 31 WebDataRequest::~WebDataRequest() {
32 manager_->MaybeCancelRequest(handle_);
33 } 33 }
34 34
35 WebDataService::Handle WebDataRequest::GetHandle() const { 35 WebDataService::Handle WebDataRequest::GetHandle() const {
36 return handle_; 36 return handle_;
37 } 37 }
38 38
39 WebDataServiceConsumer* WebDataRequest::GetConsumer() const { 39 WebDataServiceConsumer* WebDataRequest::GetConsumer() const {
40 return consumer_; 40 return consumer_;
41 } 41 }
dhollowa 2013/01/16 18:41:29 nit: extra line is needed here.
Cait (Slow) 2013/01/24 22:45:51 Done.
42 MessageLoop* WebDataRequest::GetMessageLoop() const {
43 return message_loop_;
44 }
42 45
43 bool WebDataRequest::IsCancelled() const { 46 bool WebDataRequest::IsCancelled() const {
44 base::AutoLock l(cancel_lock_); 47 base::AutoLock l(cancel_lock_);
45 return cancelled_; 48 return cancelled_;
46 } 49 }
47 50
48 void WebDataRequest::Cancel() { 51 void WebDataRequest::Cancel() {
49 base::AutoLock l(cancel_lock_); 52 base::AutoLock l(cancel_lock_);
50 cancelled_ = true; 53 cancelled_ = true;
51 consumer_ = NULL; 54 consumer_ = NULL;
52 } 55 }
53 56
54 void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) { 57 void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) {
55 result_ = r.Pass(); 58 result_ = r.Pass();
56 } 59 }
57 60
58 const WDTypedResult* WebDataRequest::GetResult() const { 61 const WDTypedResult* WebDataRequest::GetResult() const {
59 return result_.get(); 62 return result_.get();
60 } 63 }
61 64
62 void WebDataRequest::RequestComplete() {
63 message_loop_->PostTask(FROM_HERE, Bind(&WebDataService::RequestCompleted,
64 service_.get(), handle_));
65 }
66
67 //////////////////////////////////////////////////////////////////////////////// 65 ////////////////////////////////////////////////////////////////////////////////
68 // 66 //
69 // WebDataRequestManager implementation. 67 // WebDataRequestManager implementation.
70 // 68 //
71 //////////////////////////////////////////////////////////////////////////////// 69 ////////////////////////////////////////////////////////////////////////////////
72 70
73 WebDataRequestManager::WebDataRequestManager() 71 WebDataRequestManager::WebDataRequestManager()
74 : next_request_handle_(1) { 72 : next_request_handle_(1) {
75 } 73 }
76 74
77 WebDataRequestManager::~WebDataRequestManager() { 75 WebDataRequestManager::~WebDataRequestManager() {
76 base::AutoLock l(pending_lock_);
77 for (RequestMap::iterator i = pending_requests_.begin();
78 i != pending_requests_.end(); ++i) {
79 i->second->Cancel();
erikwright (departed) 2013/01/16 19:00:23 I think it's a requirement that WebDataRequest::Ca
Cait (Slow) 2013/01/24 22:45:51 Done.
80 }
81 pending_requests_.clear();
78 } 82 }
79 83
80 void WebDataRequestManager::RegisterRequest(WebDataRequest* request) { 84 void WebDataRequestManager::RegisterRequest(WebDataRequest* request) {
81 base::AutoLock l(pending_lock_); 85 base::AutoLock l(pending_lock_);
82 pending_requests_[request->GetHandle()] = request; 86 pending_requests_[request->GetHandle()] = request;
83 } 87 }
84 88
85 int WebDataRequestManager::GetNextRequestHandle() { 89 int WebDataRequestManager::GetNextRequestHandle() {
86 base::AutoLock l(pending_lock_); 90 base::AutoLock l(pending_lock_);
87 return ++next_request_handle_; 91 return ++next_request_handle_;
88 } 92 }
89 93
90 void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) { 94 bool WebDataRequestManager::MaybeCancelRequest(WebDataServiceBase::Handle h) {
91 base::AutoLock l(pending_lock_); 95 base::AutoLock l(pending_lock_);
92 RequestMap::iterator i = pending_requests_.find(h); 96 RequestMap::iterator i = pending_requests_.find(h);
93 if (i == pending_requests_.end()) { 97 if (i == pending_requests_.end()) {
dhollowa 2013/01/16 18:41:29 nit: no longer need {} for single line body.
Cait (Slow) 2013/01/24 22:45:51 Done.
94 NOTREACHED() << "Canceling a nonexistent web data service request"; 98 return false;
95 return;
96 } 99 }
97 i->second->Cancel(); 100 i->second->Cancel();
erikwright (departed) 2013/01/16 19:00:23 It seems like a bug that 'i' is not erased from pe
Cait (Slow) 2013/01/24 22:45:51 Done -- This causes a bit of weirdness in the case
101 return true;
98 } 102 }
99 103
100 void WebDataRequestManager::RequestCompleted(WebDataServiceBase::Handle h) { 104 void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) {
105 if (!MaybeCancelRequest(h)) {
106 NOTREACHED() << "Canceling a nonexistent web data service request";
dhollowa 2013/01/16 18:41:29 nit: no longer need {} for single line body.
Cait (Slow) 2013/01/24 22:45:51 Done.
107 }
108 }
109
110 void WebDataRequestManager::RequestCompleted(
111 scoped_ptr<WebDataRequest> request) {
112 MessageLoop* loop = request->GetMessageLoop();
113 loop->PostTask(FROM_HERE, base::Bind(
114 &WebDataRequestManager::RequestCompletedOnThread,
115 base::Unretained(this),
116 base::Passed(&request)));
117 }
118
119 void WebDataRequestManager::RequestCompletedOnThread(
120 scoped_ptr<WebDataRequest> request) {
101 pending_lock_.Acquire(); 121 pending_lock_.Acquire();
102 RequestMap::iterator i = pending_requests_.find(h); 122 RequestMap::iterator i = pending_requests_.find(request->GetHandle());
103 if (i == pending_requests_.end()) { 123 if (i == pending_requests_.end()) {
104 NOTREACHED() << "Request completed called for an unknown request"; 124 NOTREACHED() << "Request completed called for an unknown request";
105 pending_lock_.Release(); 125 pending_lock_.Release();
106 return; 126 return;
107 } 127 }
108 128
109 // Take ownership of the request object and remove it from the map. 129 // Take ownership of the request object and remove it from the map.
110 scoped_ptr<WebDataRequest> request(i->second);
111 pending_requests_.erase(i); 130 pending_requests_.erase(i);
112 pending_lock_.Release(); 131 pending_lock_.Release();
113 132
114 // Notify the consumer if needed. 133 // Notify the consumer if needed.
115 WebDataServiceConsumer* consumer = request->GetConsumer(); 134 WebDataServiceConsumer* consumer = request->GetConsumer();
116 if (!request->IsCancelled() && consumer) { 135 if (!request->IsCancelled() && consumer) {
117 consumer->OnWebDataServiceRequestDone(request->GetHandle(), 136 consumer->OnWebDataServiceRequestDone(request->GetHandle(),
118 request->GetResult()); 137 request->GetResult());
erikwright (departed) 2013/01/16 19:00:23 Make GetResult transfer ownership of the WDTypedRe
Cait (Slow) 2013/01/24 22:45:51 Done.
119 } else { 138 } else {
120 // Nobody is taken ownership of the result, either because it is cancelled 139 // Nobody is taken ownership of the result, either because it is cancelled
121 // or there is no consumer. Destroy results that require special handling. 140 // or there is no consumer. Destroy results that require special handling.
122 WDTypedResult const *result = request->GetResult(); 141 WDTypedResult const *result = request->GetResult();
123 if (result) { 142 if (result) {
124 result->Destroy(); 143 result->Destroy();
erikwright (departed) 2013/01/16 19:00:23 As an aside, rather than passing an optional callb
Cait (Slow) 2013/01/24 22:45:51 Done.
125 } 144 }
126 } 145 }
erikwright (departed) 2013/01/16 19:00:23 I think something at this point must tell the requ
Cait (Slow) 2013/01/24 22:45:51 Done.
127 } 146 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698