OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/cancelable_request.h" | 5 #include "chrome/browser/cancelable_request.h" |
6 | 6 |
7 CancelableRequestProvider::CancelableRequestProvider() | 7 CancelableRequestProvider::CancelableRequestProvider() |
8 : next_handle_(1) { | 8 : next_handle_(1) { |
9 } | 9 } |
10 | 10 |
11 CancelableRequestProvider::~CancelableRequestProvider() { | |
12 // There may be requests whose result callback has not been run yet. We need | |
13 // to cancel them otherwise they may try and call us back after we've been | |
14 // deleted, or do other bad things. This can occur on shutdown (or browser | |
15 // context destruction) when a request is scheduled, completed (but not | |
16 // dispatched), then the BrowserContext is deleted. | |
17 base::AutoLock lock(pending_request_lock_); | |
18 while (!pending_requests_.empty()) | |
19 CancelRequestLocked(pending_requests_.begin()); | |
20 } | |
21 | |
22 CancelableRequestProvider::Handle CancelableRequestProvider::AddRequest( | 11 CancelableRequestProvider::Handle CancelableRequestProvider::AddRequest( |
23 CancelableRequestBase* request, | 12 CancelableRequestBase* request, |
24 CancelableRequestConsumerBase* consumer) { | 13 CancelableRequestConsumerBase* consumer) { |
25 Handle handle; | 14 Handle handle; |
26 { | 15 { |
27 base::AutoLock lock(pending_request_lock_); | 16 base::AutoLock lock(pending_request_lock_); |
28 | 17 |
29 handle = next_handle_; | 18 handle = next_handle_; |
30 pending_requests_[next_handle_] = request; | 19 pending_requests_[next_handle_] = request; |
31 ++next_handle_; | 20 ++next_handle_; |
32 DCHECK(next_handle_) | 21 DCHECK(next_handle_) |
33 << "next_handle_ may have wrapped around to invalid state."; | 22 << "next_handle_ may have wrapped around to invalid state."; |
34 } | 23 } |
35 | 24 |
36 consumer->OnRequestAdded(this, handle); | 25 consumer->OnRequestAdded(this, handle); |
37 | 26 |
38 request->Init(this, handle, consumer); | 27 request->Init(this, handle, consumer); |
39 return handle; | 28 return handle; |
40 } | 29 } |
41 | 30 |
42 void CancelableRequestProvider::CancelRequest(Handle handle) { | 31 void CancelableRequestProvider::CancelRequest(Handle handle) { |
43 base::AutoLock lock(pending_request_lock_); | 32 base::AutoLock lock(pending_request_lock_); |
44 CancelRequestLocked(pending_requests_.find(handle)); | 33 CancelRequestLocked(pending_requests_.find(handle)); |
45 } | 34 } |
46 | 35 |
| 36 CancelableRequestProvider::~CancelableRequestProvider() { |
| 37 // There may be requests whose result callback has not been run yet. We need |
| 38 // to cancel them otherwise they may try and call us back after we've been |
| 39 // deleted, or do other bad things. This can occur on shutdown (or browser |
| 40 // context destruction) when a request is scheduled, completed (but not |
| 41 // dispatched), then the BrowserContext is deleted. |
| 42 base::AutoLock lock(pending_request_lock_); |
| 43 while (!pending_requests_.empty()) |
| 44 CancelRequestLocked(pending_requests_.begin()); |
| 45 } |
| 46 |
47 void CancelableRequestProvider::CancelRequestLocked( | 47 void CancelableRequestProvider::CancelRequestLocked( |
48 const CancelableRequestMap::iterator& item) { | 48 const CancelableRequestMap::iterator& item) { |
49 pending_request_lock_.AssertAcquired(); | 49 pending_request_lock_.AssertAcquired(); |
50 if (item == pending_requests_.end()) { | 50 if (item == pending_requests_.end()) { |
51 NOTREACHED() << "Trying to cancel an unknown request"; | 51 NOTREACHED() << "Trying to cancel an unknown request"; |
52 return; | 52 return; |
53 } | 53 } |
54 | 54 |
55 item->second->consumer()->OnRequestRemoved(this, item->first); | 55 item->second->consumer()->OnRequestRemoved(this, item->first); |
56 item->second->set_canceled(); | 56 item->second->set_canceled(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 // Execute the callback. | 131 // Execute the callback. |
132 forwarded_call.Run(); | 132 forwarded_call.Run(); |
133 } | 133 } |
134 | 134 |
135 // Notify the provider that the request is complete. The provider will | 135 // Notify the provider that the request is complete. The provider will |
136 // notify the consumer for us. Note that it is possible for the callback to | 136 // notify the consumer for us. Note that it is possible for the callback to |
137 // cancel this request; we must check canceled again. | 137 // cancel this request; we must check canceled again. |
138 if (!canceled_.IsSet()) | 138 if (!canceled_.IsSet()) |
139 NotifyCompleted(); | 139 NotifyCompleted(); |
140 } | 140 } |
OLD | NEW |