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

Side by Side Diff: chrome/browser/prerender/prerender_tracker.cc

Issue 7038012: Safely cancel prerenders on threads other than the UI thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix linux Created 9 years, 7 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/logging.h"
6 #include "chrome/browser/prerender/prerender_manager.h"
7 #include "chrome/browser/prerender/prerender_tracker.h"
8 #include "content/browser/browser_thread.h"
9
10 namespace prerender {
11
12 namespace {
13
14 void DestroyPreloadForRenderView(
15 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr,
16 int child_id,
17 int route_id,
18 FinalStatus final_status) {
19 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
20 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get();
21 if (!prerender_manager)
22 return;
23
24 prerender_manager->DestroyPreloadForChildRouteIdPair(
25 std::make_pair(child_id, route_id),
26 final_status);
27 }
28
29 } // namespace
30
31 struct RenderViewInfo {
32 FinalStatus final_status;
dominich 2011/05/19 16:07:27 Should this have a constructor that takes the Prer
mmenke 2011/05/19 16:40:42 In order to do that, I'd also have to make a const
dominich 2011/05/19 16:55:47 I think that's only if you use operator[]. If you
mmenke 2011/05/19 17:19:10 You're right. Done as you suggest.
33 base::WeakPtr<PrerenderManager> prerender_manager;
34 };
35
36 // static
37 PrerenderTracker* PrerenderTracker::GetInstance() {
38 return Singleton<PrerenderTracker>::get();
39 }
40
41 bool PrerenderTracker::TryUse(int child_id, int route_id) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
43
44 FinalStatus final_status = SetFinalStatus(child_id, route_id,
45 FINAL_STATUS_USED);
46 return final_status == FINAL_STATUS_USED;
47 }
48
49 bool PrerenderTracker::TryCancel(
50 int child_id,
51 int route_id,
52 FinalStatus final_status) {
53 DCHECK_NE(FINAL_STATUS_USED, final_status);
54 DCHECK(final_status >= 0 && final_status < FINAL_STATUS_MAX);
55
56 final_status = SetFinalStatus(child_id, route_id, final_status);
57 return final_status != FINAL_STATUS_USED && final_status != FINAL_STATUS_MAX;
58 }
59
60 bool PrerenderTracker::TryCancelOnIOThread(
61 int child_id,
62 int route_id,
63 FinalStatus final_status) {
64 DCHECK_NE(FINAL_STATUS_USED, final_status);
65 DCHECK(final_status >= 0 && final_status < FINAL_STATUS_MAX);
66
67 if (!IsPrerenderingOnIOThread(child_id, route_id))
68 return false;
69 return TryCancel(child_id, route_id, final_status);
70 }
71
72 bool PrerenderTracker::IsPrerenderingOnIOThread(int child_id, int route_id) {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
74
75 std::pair<int, int> child_route_id_pair(child_id, route_id);
76 return possibly_prerendering_io_thread_set_.end() !=
77 possibly_prerendering_io_thread_set_.find(child_route_id_pair);
78 }
79
80 bool PrerenderTracker::GetFinalStatus(int child_id, int route_id,
81 FinalStatus* final_status) {
82 std::pair<int, int> child_route_id_pair(child_id, route_id);
83
84 base::AutoLock lock(lock_);
85 FinalStatusMap::iterator final_status_it =
86 final_status_map_.find(child_route_id_pair);
87 if (final_status_map_.end() == final_status_map_.find(child_route_id_pair))
88 return false;
89 *final_status = final_status_it->second.final_status;
90 return true;
91 }
92
93 void PrerenderTracker::OnPrerenderingStarted(
94 int child_id, int route_id, PrerenderManager* prerender_manager) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 DCHECK_NE(-1, child_id);
97 DCHECK_NE(-1, route_id);
98
99 std::pair<int, int> child_route_id_pair(child_id, route_id);
100
101 // The RenderView should not already be prerendering.
102 DCHECK(final_status_map_.end() ==
103 final_status_map_.find(child_route_id_pair));
104
105 BrowserThread::PostTask(
106 BrowserThread::IO, FROM_HERE,
107 NewRunnableFunction(&AddPrerenderOnIOThreadTask, child_route_id_pair));
108
109 base::AutoLock lock(lock_);
110 final_status_map_[child_route_id_pair].final_status = FINAL_STATUS_MAX;
111 final_status_map_[child_route_id_pair].prerender_manager =
112 prerender_manager->AsWeakPtr();
113 }
114
115 void PrerenderTracker::OnPrerenderingFinished(int child_id, int route_id) {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
117 DCHECK_NE(-1, child_id);
118 DCHECK_NE(-1, route_id);
119
120 std::pair<int, int> child_route_id_pair(child_id, route_id);
121
122 BrowserThread::PostTask(
123 BrowserThread::IO, FROM_HERE,
124 NewRunnableFunction(&RemovePrerenderOnIOThreadTask, child_route_id_pair));
125
126 base::AutoLock lock(lock_);
127 size_t num_erased = final_status_map_.erase(child_route_id_pair);
128 DCHECK_EQ(1u, num_erased);
129 }
130
131 PrerenderTracker::PrerenderTracker() {
132 }
133
134 PrerenderTracker::~PrerenderTracker() {
135 }
136
137 FinalStatus PrerenderTracker::SetFinalStatus(int child_id, int route_id,
138 FinalStatus final_status) {
139 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX);
140
141 std::pair<int, int> child_route_id_pair(child_id, route_id);
142
143 base::AutoLock lock(lock_);
144 FinalStatusMap::iterator final_status_it =
145 final_status_map_.find(child_route_id_pair);
146 if (final_status_it == final_status_map_.end()) {
147 // The RenderView has already been either used or destroyed.
148 return FINAL_STATUS_MAX;
149 }
150
151 if (final_status_it->second.final_status == FINAL_STATUS_MAX) {
152 final_status_it->second.final_status = final_status;
153 if (final_status != FINAL_STATUS_USED) {
154 BrowserThread::PostTask(
155 BrowserThread::UI, FROM_HERE,
156 NewRunnableFunction(&DestroyPreloadForRenderView,
157 final_status_it->second.prerender_manager,
158 child_id,
159 route_id,
160 final_status));
161 }
162 }
163 return final_status_it->second.final_status;
164 }
165
166 void PrerenderTracker::AddPrerenderOnIOThread(
167 const std::pair<int, int>& child_route_id_pair) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
169 DCHECK(!IsPrerenderingOnIOThread(child_route_id_pair.first,
170 child_route_id_pair.second));
171
172 possibly_prerendering_io_thread_set_.insert(child_route_id_pair);
173 }
174
175 void PrerenderTracker::RemovePrerenderOnIOThread(
176 const std::pair<int, int>& child_route_id_pair) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
178 DCHECK(IsPrerenderingOnIOThread(child_route_id_pair.first,
179 child_route_id_pair.second));
180
181 possibly_prerendering_io_thread_set_.erase(child_route_id_pair);
182 }
183
184 // static
185 void PrerenderTracker::AddPrerenderOnIOThreadTask(
186 const std::pair<int, int>& child_route_id_pair) {
187 GetInstance()->AddPrerenderOnIOThread(child_route_id_pair);
188 }
189
190 // static
191 void PrerenderTracker::RemovePrerenderOnIOThreadTask(
192 const std::pair<int, int>& child_route_id_pair) {
193 GetInstance()->RemovePrerenderOnIOThread(child_route_id_pair);
194 }
195
196 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698