OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/frame_tree.h" | 5 #include "content/browser/frame_host/frame_tree.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 161 |
162 RenderViewHostImpl* FrameTree::CreateRenderViewHostForMainFrame( | 162 RenderViewHostImpl* FrameTree::CreateRenderViewHostForMainFrame( |
163 SiteInstance* site_instance, | 163 SiteInstance* site_instance, |
164 int routing_id, | 164 int routing_id, |
165 int main_frame_routing_id, | 165 int main_frame_routing_id, |
166 bool swapped_out, | 166 bool swapped_out, |
167 bool hidden) { | 167 bool hidden) { |
168 DCHECK(main_frame_routing_id != MSG_ROUTING_NONE); | 168 DCHECK(main_frame_routing_id != MSG_ROUTING_NONE); |
169 RenderViewHostMap::iterator iter = | 169 RenderViewHostMap::iterator iter = |
170 render_view_host_map_.find(site_instance->GetId()); | 170 render_view_host_map_.find(site_instance->GetId()); |
171 CHECK(iter == render_view_host_map_.end()); | 171 if (iter != render_view_host_map_.end()) { |
| 172 // If a RenderViewHost is pending shutdown for this |site_instance|, put it |
| 173 // in the map of RenderViewHosts pending shutdown. Otherwise there should |
| 174 // not be a RenderViewHost for the SiteInstance. |
| 175 CHECK_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, |
| 176 iter->second->rvh_state()); |
| 177 render_view_host_pending_shutdown_map_.insert( |
| 178 std::pair<int, RenderViewHostImpl*>(site_instance->GetId(), |
| 179 iter->second)); |
| 180 render_view_host_map_.erase(iter); |
| 181 } |
172 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( | 182 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( |
173 RenderViewHostFactory::Create(site_instance, | 183 RenderViewHostFactory::Create(site_instance, |
174 render_view_delegate_, | 184 render_view_delegate_, |
175 render_widget_delegate_, | 185 render_widget_delegate_, |
176 routing_id, | 186 routing_id, |
177 main_frame_routing_id, | 187 main_frame_routing_id, |
178 swapped_out, | 188 swapped_out, |
179 hidden)); | 189 hidden)); |
180 | 190 |
181 render_view_host_map_[site_instance->GetId()] = | 191 render_view_host_map_[site_instance->GetId()] = rvh; |
182 RenderViewHostRefCount(rvh, 0); | |
183 return rvh; | 192 return rvh; |
184 } | 193 } |
185 | 194 |
186 RenderViewHostImpl* FrameTree::GetRenderViewHostForSubFrame( | 195 RenderViewHostImpl* FrameTree::GetRenderViewHostForSubFrame( |
187 SiteInstance* site_instance) { | 196 SiteInstance* site_instance) { |
188 RenderViewHostMap::iterator iter = | 197 RenderViewHostMap::iterator iter = |
189 render_view_host_map_.find(site_instance->GetId()); | 198 render_view_host_map_.find(site_instance->GetId()); |
190 // TODO(creis): Mirror the frame tree so this check can't fail. | 199 // TODO(creis): Mirror the frame tree so this check can't fail. |
191 if (iter == render_view_host_map_.end()) | 200 if (iter == render_view_host_map_.end()) |
192 return NULL; | 201 return NULL; |
193 RenderViewHostRefCount rvh_refcount = iter->second; | 202 return iter->second; |
194 return rvh_refcount.first; | |
195 } | 203 } |
196 | 204 |
197 void FrameTree::RegisterRenderFrameHost( | 205 void FrameTree::RegisterRenderFrameHost( |
198 RenderFrameHostImpl* render_frame_host) { | 206 RenderFrameHostImpl* render_frame_host) { |
199 SiteInstance* site_instance = | 207 SiteInstance* site_instance = |
200 render_frame_host->render_view_host()->GetSiteInstance(); | 208 render_frame_host->render_view_host()->GetSiteInstance(); |
201 RenderViewHostMap::iterator iter = | 209 RenderViewHostMap::iterator iter = |
202 render_view_host_map_.find(site_instance->GetId()); | 210 render_view_host_map_.find(site_instance->GetId()); |
203 CHECK(iter != render_view_host_map_.end()); | 211 CHECK(iter != render_view_host_map_.end()); |
204 | 212 |
205 // Increment the refcount. | 213 iter->second->increment_ref_count(); |
206 CHECK_GE(iter->second.second, 0); | |
207 iter->second.second++; | |
208 } | 214 } |
209 | 215 |
210 void FrameTree::UnregisterRenderFrameHost( | 216 void FrameTree::UnregisterRenderFrameHost( |
211 RenderFrameHostImpl* render_frame_host) { | 217 RenderFrameHostImpl* render_frame_host) { |
212 SiteInstance* site_instance = | 218 SiteInstance* site_instance = |
213 render_frame_host->render_view_host()->GetSiteInstance(); | 219 render_frame_host->render_view_host()->GetSiteInstance(); |
| 220 int32 site_instance_id = site_instance->GetId(); |
214 RenderViewHostMap::iterator iter = | 221 RenderViewHostMap::iterator iter = |
215 render_view_host_map_.find(site_instance->GetId()); | 222 render_view_host_map_.find(site_instance_id); |
216 CHECK(iter != render_view_host_map_.end()); | 223 if (iter != render_view_host_map_.end() && |
217 | 224 iter->second == render_frame_host->render_view_host()) { |
218 // Decrement the refcount and shutdown the RenderViewHost if no one else is | 225 // Decrement the refcount and shutdown the RenderViewHost if no one else is |
219 // using it. | 226 // using it. |
220 CHECK_GT(iter->second.second, 0); | 227 CHECK_GT(iter->second->ref_count(), 0); |
221 iter->second.second--; | 228 iter->second->decrement_ref_count(); |
222 if (iter->second.second == 0) { | 229 if (iter->second->ref_count() == 0) { |
223 iter->second.first->Shutdown(); | 230 iter->second->Shutdown(); |
224 render_view_host_map_.erase(iter); | 231 render_view_host_map_.erase(iter); |
| 232 } |
| 233 } else { |
| 234 // The RenderViewHost should be in the list of RenderViewHosts pending |
| 235 // shutdown. |
| 236 bool render_view_host_found = false; |
| 237 std::pair<RenderViewHostMultiMap::iterator, |
| 238 RenderViewHostMultiMap::iterator> result = |
| 239 render_view_host_pending_shutdown_map_.equal_range(site_instance_id); |
| 240 for (RenderViewHostMultiMap::iterator multi_iter = result.first; |
| 241 multi_iter != result.second; |
| 242 ++multi_iter) { |
| 243 if (multi_iter->second != render_frame_host->render_view_host()) |
| 244 continue; |
| 245 render_view_host_found = true; |
| 246 RenderViewHostImpl* rvh = multi_iter->second; |
| 247 // Decrement the refcount and shutdown the RenderViewHost if no one else |
| 248 // is using it. |
| 249 CHECK_GT(rvh->ref_count(), 0); |
| 250 rvh->decrement_ref_count(); |
| 251 if (rvh->ref_count() == 0) { |
| 252 rvh->Shutdown(); |
| 253 render_view_host_pending_shutdown_map_.erase(multi_iter); |
| 254 } |
| 255 break; |
| 256 } |
| 257 CHECK(render_view_host_found); |
225 } | 258 } |
226 } | 259 } |
227 | 260 |
228 } // namespace content | 261 } // namespace content |
OLD | NEW |