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

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: Fix tsan bug Created 7 years, 10 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(WebDataServiceConsumer* consumer,
21 WebDataServiceConsumer* consumer,
22 WebDataRequestManager* manager) 19 WebDataRequestManager* manager)
23 : service_(service), 20 : manager_(manager),
24 cancelled_(false), 21 cancelled_(false),
25 consumer_(consumer), 22 consumer_(consumer),
26 result_(NULL) { 23 result_(NULL) {
27 handle_ = manager->GetNextRequestHandle(); 24 handle_ = manager_->GetNextRequestHandle();
28 message_loop_ = MessageLoop::current(); 25 message_loop_ = MessageLoop::current();
29 manager->RegisterRequest(this); 26 manager_->RegisterRequest(this);
30 } 27 }
31 28
32 WebDataRequest::~WebDataRequest() { 29 WebDataRequest::~WebDataRequest() {
30 if (manager_) {
31 manager_->CancelRequest(handle_);
32 }
33 if (result_.get()) {
34 result_->Destroy();
35 }
33 } 36 }
34 37
35 WebDataService::Handle WebDataRequest::GetHandle() const { 38 WebDataService::Handle WebDataRequest::GetHandle() const {
36 return handle_; 39 return handle_;
37 } 40 }
38 41
39 WebDataServiceConsumer* WebDataRequest::GetConsumer() const { 42 WebDataServiceConsumer* WebDataRequest::GetConsumer() const {
40 return consumer_; 43 return consumer_;
41 } 44 }
42 45
46 MessageLoop* WebDataRequest::GetMessageLoop() const {
47 return message_loop_;
48 }
49
43 bool WebDataRequest::IsCancelled() const { 50 bool WebDataRequest::IsCancelled() const {
44 base::AutoLock l(cancel_lock_); 51 base::AutoLock l(cancel_lock_);
45 return cancelled_; 52 return cancelled_;
46 } 53 }
47 54
48 void WebDataRequest::Cancel() { 55 void WebDataRequest::Cancel() {
49 base::AutoLock l(cancel_lock_); 56 base::AutoLock l(cancel_lock_);
50 cancelled_ = true; 57 cancelled_ = true;
51 consumer_ = NULL; 58 consumer_ = NULL;
59 manager_ = NULL;
60 }
61
62 void WebDataRequest::OnComplete() {
63 manager_= NULL;
52 } 64 }
53 65
54 void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) { 66 void WebDataRequest::SetResult(scoped_ptr<WDTypedResult> r) {
55 result_ = r.Pass(); 67 result_ = r.Pass();
56 } 68 }
57 69
58 const WDTypedResult* WebDataRequest::GetResult() const { 70 scoped_ptr<WDTypedResult> WebDataRequest::GetResult(){
59 return result_.get(); 71 return result_.Pass();
60 }
61
62 void WebDataRequest::RequestComplete() {
63 message_loop_->PostTask(FROM_HERE, Bind(&WebDataService::RequestCompleted,
64 service_.get(), handle_));
65 } 72 }
66 73
67 //////////////////////////////////////////////////////////////////////////////// 74 ////////////////////////////////////////////////////////////////////////////////
68 // 75 //
69 // WebDataRequestManager implementation. 76 // WebDataRequestManager implementation.
70 // 77 //
71 //////////////////////////////////////////////////////////////////////////////// 78 ////////////////////////////////////////////////////////////////////////////////
72 79
73 WebDataRequestManager::WebDataRequestManager() 80 WebDataRequestManager::WebDataRequestManager()
74 : next_request_handle_(1) { 81 : next_request_handle_(1) {
75 } 82 }
76 83
77 WebDataRequestManager::~WebDataRequestManager() { 84 WebDataRequestManager::~WebDataRequestManager() {
85 base::AutoLock l(pending_lock_);
86 for (RequestMap::iterator i = pending_requests_.begin();
87 i != pending_requests_.end(); ++i) {
88 i->second->Cancel();
89 }
90 pending_requests_.clear();
78 } 91 }
79 92
80 void WebDataRequestManager::RegisterRequest(WebDataRequest* request) { 93 void WebDataRequestManager::RegisterRequest(WebDataRequest* request) {
81 base::AutoLock l(pending_lock_); 94 base::AutoLock l(pending_lock_);
82 pending_requests_[request->GetHandle()] = request; 95 pending_requests_[request->GetHandle()] = request;
83 } 96 }
84 97
85 int WebDataRequestManager::GetNextRequestHandle() { 98 int WebDataRequestManager::GetNextRequestHandle() {
86 base::AutoLock l(pending_lock_); 99 base::AutoLock l(pending_lock_);
87 return ++next_request_handle_; 100 return ++next_request_handle_;
88 } 101 }
89 102
90 void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) { 103 void WebDataRequestManager::CancelRequest(WebDataServiceBase::Handle h) {
91 base::AutoLock l(pending_lock_); 104 base::AutoLock l(pending_lock_);
92 RequestMap::iterator i = pending_requests_.find(h); 105 RequestMap::iterator i = pending_requests_.find(h);
93 if (i == pending_requests_.end()) { 106 if (i == pending_requests_.end()) {
94 NOTREACHED() << "Canceling a nonexistent web data service request"; 107 NOTREACHED() << "Canceling a nonexistent web data service request";
95 return; 108 return;
96 } 109 }
97 i->second->Cancel(); 110 i->second->Cancel();
111 pending_requests_.erase(i);
98 } 112 }
99 113
100 void WebDataRequestManager::RequestCompleted(WebDataServiceBase::Handle h) { 114 void WebDataRequestManager::RequestCompleted(
101 pending_lock_.Acquire(); 115 scoped_ptr<WebDataRequest> request) {
102 RequestMap::iterator i = pending_requests_.find(h); 116 MessageLoop* loop = request->GetMessageLoop();
103 if (i == pending_requests_.end()) { 117 loop->PostTask(FROM_HERE, base::Bind(
104 NOTREACHED() << "Request completed called for an unknown request"; 118 &WebDataRequestManager::RequestCompletedOnThread,
105 pending_lock_.Release(); 119 this,
120 base::Passed(&request)));
121 }
122
123 void WebDataRequestManager::RequestCompletedOnThread(
124 scoped_ptr<WebDataRequest> request) {
125 if (request->IsCancelled())
106 return; 126 return;
127 {
128 base::AutoLock l(pending_lock_);
129 RequestMap::iterator i = pending_requests_.find(request->GetHandle());
130 if (i == pending_requests_.end()) {
131 NOTREACHED() << "Request completed called for an unknown request";
132 return;
133 }
134
135 // Take ownership of the request object and remove it from the map.
136 pending_requests_.erase(i);
107 } 137 }
108 138
109 // Take ownership of the request object and remove it from the map.
110 scoped_ptr<WebDataRequest> request(i->second);
111 pending_requests_.erase(i);
112 pending_lock_.Release();
113
114 // Notify the consumer if needed. 139 // Notify the consumer if needed.
115 WebDataServiceConsumer* consumer = request->GetConsumer(); 140 if (!request->IsCancelled()) {
116 if (!request->IsCancelled() && consumer) { 141 WebDataServiceConsumer* consumer = request->GetConsumer();
117 consumer->OnWebDataServiceRequestDone(request->GetHandle(), 142 request->OnComplete();
118 request->GetResult()); 143 if (consumer) {
119 } else { 144 scoped_ptr<WDTypedResult> r = request->GetResult();
120 // Nobody is taken ownership of the result, either because it is cancelled 145 consumer->OnWebDataServiceRequestDone(request->GetHandle(), r.get());
121 // or there is no consumer. Destroy results that require special handling.
122 WDTypedResult const *result = request->GetResult();
123 if (result) {
124 result->Destroy();
125 } 146 }
126 } 147 }
148
127 } 149 }
OLDNEW
« no previous file with comments | « chrome/browser/webdata/web_data_request_manager.h ('k') | chrome/browser/webdata/web_data_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698