Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/prerender/prerender_tracker.h" | 5 #include "chrome/browser/prerender/prerender_tracker.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "chrome/browser/browser_process.h" | 9 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/prerender/prerender_manager.h" | 10 #include "chrome/browser/prerender/prerender_manager.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 : final_status(FINAL_STATUS_MAX), | 41 : final_status(FINAL_STATUS_MAX), |
| 42 prerender_manager(prerender_manager->AsWeakPtr()) { | 42 prerender_manager(prerender_manager->AsWeakPtr()) { |
| 43 } | 43 } |
| 44 ~RenderViewInfo() {} | 44 ~RenderViewInfo() {} |
| 45 | 45 |
| 46 FinalStatus final_status; | 46 FinalStatus final_status; |
| 47 base::WeakPtr<PrerenderManager> prerender_manager; | 47 base::WeakPtr<PrerenderManager> prerender_manager; |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 PrerenderTracker::PrerenderTracker() { | 50 PrerenderTracker::PrerenderTracker() { |
| 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 51 } | 52 } |
| 52 | 53 |
| 53 PrerenderTracker::~PrerenderTracker() { | 54 PrerenderTracker::~PrerenderTracker() { |
| 55 for (std::set<PrerenderContents*>::iterator it = observing_set_.begin(); | |
| 56 it != observing_set_.end(); ++it) { | |
| 57 (*it)->RemoveObserver(this); | |
| 58 } | |
|
mmenke
2012/12/03 20:02:47
Isn't the PrerenderTracker shut down after the las
gavinp
2012/12/04 18:04:48
Done.
| |
| 54 } | 59 } |
| 55 | 60 |
| 61 void PrerenderTracker::AddPrerenderContents( | |
| 62 PrerenderContents* prerender_contents) { | |
| 63 DCHECK(CalledOnValidThread()); | |
| 64 prerender_contents->AddObserver(this); | |
| 65 observing_set_.insert(prerender_contents); | |
| 66 } | |
| 67 | |
| 68 | |
|
mmenke
2012/12/03 20:02:47
nit: Extra line break not needed.
gavinp
2012/12/04 18:04:48
Done.
| |
| 56 bool PrerenderTracker::TryUse(int child_id, int route_id) { | 69 bool PrerenderTracker::TryUse(int child_id, int route_id) { |
| 57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 70 DCHECK(CalledOnValidThread()); |
| 58 | |
| 59 return SetFinalStatus(child_id, route_id, FINAL_STATUS_USED, NULL); | 71 return SetFinalStatus(child_id, route_id, FINAL_STATUS_USED, NULL); |
| 60 } | 72 } |
| 61 | 73 |
| 62 bool PrerenderTracker::TryCancel( | 74 bool PrerenderTracker::TryCancel( |
| 63 int child_id, | 75 int child_id, |
| 64 int route_id, | 76 int route_id, |
| 65 FinalStatus final_status) { | 77 FinalStatus final_status) { |
| 66 DCHECK_NE(FINAL_STATUS_USED, final_status); | 78 DCHECK_NE(FINAL_STATUS_USED, final_status); |
| 67 DCHECK(final_status >= 0 && final_status < FINAL_STATUS_MAX); | 79 DCHECK(final_status >= 0 && final_status < FINAL_STATUS_MAX); |
| 68 | 80 |
| 69 FinalStatus actual_final_status; | 81 FinalStatus actual_final_status; |
| 70 SetFinalStatus(child_id, route_id, final_status, &actual_final_status); | 82 SetFinalStatus(child_id, route_id, final_status, &actual_final_status); |
| 71 return actual_final_status != FINAL_STATUS_USED && | 83 return actual_final_status != FINAL_STATUS_USED && |
| 72 actual_final_status != FINAL_STATUS_MAX; | 84 actual_final_status != FINAL_STATUS_MAX; |
| 73 } | 85 } |
| 74 | 86 |
| 75 bool PrerenderTracker::TryCancelOnIOThread( | 87 bool PrerenderTracker::TryCancelOnIOThread( |
| 76 int child_id, | 88 int child_id, |
| 77 int route_id, | 89 int route_id, |
| 78 FinalStatus final_status) { | 90 FinalStatus final_status) { |
| 79 DCHECK_NE(FINAL_STATUS_USED, final_status); | 91 DCHECK_NE(FINAL_STATUS_USED, final_status); |
| 80 DCHECK(final_status >= 0 && final_status < FINAL_STATUS_MAX); | 92 DCHECK_LE(0, final_status); |
| 93 DCHECK_GT(FINAL_STATUS_MAX, final_status); | |
| 81 | 94 |
| 82 if (!IsPrerenderingOnIOThread(child_id, route_id)) | 95 if (!IsPrerenderingOnIOThread(child_id, route_id)) |
| 83 return false; | 96 return false; |
| 84 return TryCancel(child_id, route_id, final_status); | 97 return TryCancel(child_id, route_id, final_status); |
| 85 } | 98 } |
| 86 | 99 |
| 87 bool PrerenderTracker::GetFinalStatus(int child_id, int route_id, | 100 bool PrerenderTracker::GetFinalStatus(int child_id, int route_id, |
| 88 FinalStatus* final_status) const { | 101 FinalStatus* final_status) const { |
| 89 ChildRouteIdPair child_route_id_pair(child_id, route_id); | 102 ChildRouteIdPair child_route_id_pair(child_id, route_id); |
| 90 | 103 |
| 91 base::AutoLock lock(final_status_map_lock_); | 104 base::AutoLock lock(final_status_map_lock_); |
| 92 FinalStatusMap::const_iterator final_status_it = | 105 FinalStatusMap::const_iterator final_status_it = |
| 93 final_status_map_.find(child_route_id_pair); | 106 final_status_map_.find(child_route_id_pair); |
| 94 if (final_status_map_.end() == final_status_map_.find(child_route_id_pair)) | 107 if (final_status_map_.count(child_route_id_pair) == 0) |
| 95 return false; | 108 return false; |
| 96 *final_status = final_status_it->second.final_status; | 109 *final_status = final_status_it->second.final_status; |
| 97 return true; | 110 return true; |
| 98 } | 111 } |
| 99 | 112 |
| 100 void PrerenderTracker::OnPrerenderingStarted( | 113 void PrerenderTracker::OnPrerenderStart( |
| 101 int child_id, int route_id, PrerenderManager* prerender_manager) { | 114 PrerenderContents* prerender_contents) { |
| 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 115 DCHECK(CalledOnValidThread()); |
| 103 DCHECK_GE(child_id, 0); | 116 int child_id; |
| 104 DCHECK_GE(route_id, 0); | 117 if (!prerender_contents->GetChildId(&child_id)) |
| 118 return; | |
| 119 int route_id; | |
| 120 if (!prerender_contents->GetRouteId(&route_id)) | |
| 121 return; | |
|
mmenke
2012/12/03 20:02:47
nit: May be a little prettier if these if stateme
gavinp
2012/12/04 18:04:48
I'm going to go ahead and ignore this nit from thi
| |
| 105 | 122 |
| 106 ChildRouteIdPair child_route_id_pair(child_id, route_id); | 123 ChildRouteIdPair child_route_id_pair(child_id, route_id); |
| 107 | 124 |
| 108 // The RenderView should not already be prerendering. | 125 // The RenderView should not already be prerendering. |
| 109 DCHECK(final_status_map_.end() == | 126 DCHECK_EQ(0u, final_status_map_.count(child_route_id_pair)); |
| 110 final_status_map_.find(child_route_id_pair)); | |
| 111 | 127 |
| 112 BrowserThread::PostTask( | 128 BrowserThread::PostTask( |
| 113 BrowserThread::IO, FROM_HERE, | 129 BrowserThread::IO, FROM_HERE, |
| 114 base::Bind(&AddPrerenderOnIOThreadTask, child_route_id_pair)); | 130 base::Bind(&AddPrerenderOnIOThreadTask, child_route_id_pair)); |
| 115 | 131 |
| 116 base::AutoLock lock(final_status_map_lock_); | 132 base::AutoLock lock(final_status_map_lock_); |
| 117 | 133 |
| 118 final_status_map_.insert( | 134 final_status_map_.insert( |
| 119 std::make_pair(child_route_id_pair, RenderViewInfo(prerender_manager))); | 135 std::make_pair(child_route_id_pair, |
| 136 RenderViewInfo(prerender_contents->prerender_manager()))); | |
| 120 } | 137 } |
| 121 | 138 |
| 122 void PrerenderTracker::OnPrerenderingFinished(int child_id, int route_id) { | 139 void PrerenderTracker::OnPrerenderStop( |
| 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 140 PrerenderContents* prerender_contents) { |
| 124 DCHECK_GE(child_id, 0); | 141 DCHECK(CalledOnValidThread()); |
| 125 DCHECK_GE(route_id, 0); | 142 prerender_contents->RemoveObserver(this); |
|
mmenke
2012/12/03 20:02:47
Wonder if we should just clear the observer list i
gavinp
2012/12/04 18:04:48
That's a great idea; it avoids a ton of crashes.
| |
| 143 observing_set_.erase(prerender_contents); | |
|
mmenke
2012/12/03 20:02:47
Suggest a DCHECK_EQ(1, observer_set_.count(prerend
gavinp
2012/12/04 18:04:48
Done. This turned out to require a significant rew
| |
| 144 int child_id; | |
| 145 if (!prerender_contents->GetChildId(&child_id)) | |
| 146 return; | |
| 147 int route_id; | |
| 148 if (!prerender_contents->GetRouteId(&route_id)) | |
| 149 return; | |
|
mmenke
2012/12/03 20:02:47
nit: May be a little prettier if these if stateme
| |
| 126 | 150 |
| 127 ChildRouteIdPair child_route_id_pair(child_id, route_id); | 151 ChildRouteIdPair child_route_id_pair(child_id, route_id); |
| 128 | 152 |
| 129 BrowserThread::PostTask( | 153 BrowserThread::PostTask( |
| 130 BrowserThread::IO, FROM_HERE, | 154 BrowserThread::IO, FROM_HERE, |
| 131 base::Bind(&RemovePrerenderOnIOThreadTask, child_route_id_pair)); | 155 base::Bind(&RemovePrerenderOnIOThreadTask, child_route_id_pair)); |
| 132 | 156 |
| 133 base::AutoLock lock(final_status_map_lock_); | 157 base::AutoLock lock(final_status_map_lock_); |
| 134 size_t num_erased = final_status_map_.erase(child_route_id_pair); | 158 size_t num_erased = final_status_map_.erase(child_route_id_pair); |
| 135 DCHECK_EQ(1u, num_erased); | 159 DCHECK_EQ(1u, num_erased); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 if (actual_final_status) | 195 if (actual_final_status) |
| 172 *actual_final_status = final_status_it->second.final_status; | 196 *actual_final_status = final_status_it->second.final_status; |
| 173 return false; | 197 return false; |
| 174 } | 198 } |
| 175 | 199 |
| 176 bool PrerenderTracker::IsPrerenderingOnIOThread(int child_id, | 200 bool PrerenderTracker::IsPrerenderingOnIOThread(int child_id, |
| 177 int route_id) const { | 201 int route_id) const { |
| 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 179 | 203 |
| 180 ChildRouteIdPair child_route_id_pair(child_id, route_id); | 204 ChildRouteIdPair child_route_id_pair(child_id, route_id); |
| 181 return possibly_prerendering_io_thread_set_.end() != | 205 return possibly_prerendering_io_thread_set_.count(child_route_id_pair) > 0; |
| 182 possibly_prerendering_io_thread_set_.find(child_route_id_pair); | |
| 183 } | 206 } |
| 184 | 207 |
| 185 void PrerenderTracker::AddPrerenderOnIOThread( | 208 void PrerenderTracker::AddPrerenderOnIOThread( |
| 186 const ChildRouteIdPair& child_route_id_pair) { | 209 const ChildRouteIdPair& child_route_id_pair) { |
| 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 188 DCHECK(!IsPrerenderingOnIOThread(child_route_id_pair.first, | 211 DCHECK(!IsPrerenderingOnIOThread(child_route_id_pair.first, |
| 189 child_route_id_pair.second)); | 212 child_route_id_pair.second)); |
| 190 | 213 |
| 191 possibly_prerendering_io_thread_set_.insert(child_route_id_pair); | 214 possibly_prerendering_io_thread_set_.insert(child_route_id_pair); |
| 192 } | 215 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 211 GetDefault()->AddPrerenderOnIOThread(child_route_id_pair); | 234 GetDefault()->AddPrerenderOnIOThread(child_route_id_pair); |
| 212 } | 235 } |
| 213 | 236 |
| 214 // static | 237 // static |
| 215 void PrerenderTracker::RemovePrerenderOnIOThreadTask( | 238 void PrerenderTracker::RemovePrerenderOnIOThreadTask( |
| 216 const ChildRouteIdPair& child_route_id_pair) { | 239 const ChildRouteIdPair& child_route_id_pair) { |
| 217 GetDefault()->RemovePrerenderOnIOThread(child_route_id_pair); | 240 GetDefault()->RemovePrerenderOnIOThread(child_route_id_pair); |
| 218 } | 241 } |
| 219 | 242 |
| 220 } // namespace prerender | 243 } // namespace prerender |
| OLD | NEW |