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

Side by Side Diff: chrome/browser/tabs/tab_strip_model.cc

Issue 4687009: Fixes possible crash in TabStripModel. If during close all a tab was (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 10 years, 1 month 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
« no previous file with comments | « no previous file | chrome/browser/tabs/tab_strip_model_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/tabs/tab_strip_model.h" 5 #include "chrome/browser/tabs/tab_strip_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 782
783 bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const { 783 bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const {
784 return LowerCaseEqualsASCII(contents->GetURL().spec(), 784 return LowerCaseEqualsASCII(contents->GetURL().spec(),
785 chrome::kChromeUINewTabURL) && 785 chrome::kChromeUINewTabURL) &&
786 contents == GetContentsAt(count() - 1) && 786 contents == GetContentsAt(count() - 1) &&
787 contents->controller().entry_count() == 1; 787 contents->controller().entry_count() == 1;
788 } 788 }
789 789
790 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices, 790 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices,
791 uint32 close_types) { 791 uint32 close_types) {
792 if (indices.empty())
793 return true;
794
792 bool retval = true; 795 bool retval = true;
793 796
797 // Map the indices to TabContents, that way if deleting a tab deletes other
798 // tabs we're ok.
Ben Goodger (Google) 2010/11/11 22:20:28 Can you mention what situations would cause one ta
799 std::vector<TabContents*> tabs;
800 for (size_t i = 0; i < indices.size(); ++i)
801 tabs.push_back(GetContentsAt(indices[i]));
802
794 // We only try the fast shutdown path if the whole browser process is *not* 803 // We only try the fast shutdown path if the whole browser process is *not*
795 // shutting down. Fast shutdown during browser termination is handled in 804 // shutting down. Fast shutdown during browser termination is handled in
796 // BrowserShutdown. 805 // BrowserShutdown.
797 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { 806 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) {
798 // Construct a map of processes to the number of associated tabs that are 807 // Construct a map of processes to the number of associated tabs that are
799 // closing. 808 // closing.
800 std::map<RenderProcessHost*, size_t> processes; 809 std::map<RenderProcessHost*, size_t> processes;
801 for (size_t i = 0; i < indices.size(); ++i) { 810 for (size_t i = 0; i < indices.size(); ++i) {
802 if (!delegate_->CanCloseContentsAt(indices[i])) { 811 if (!delegate_->CanCloseContentsAt(indices[i])) {
803 retval = false; 812 retval = false;
(...skipping 13 matching lines...) Expand all
817 826
818 // Try to fast shutdown the tabs that can close. 827 // Try to fast shutdown the tabs that can close.
819 for (std::map<RenderProcessHost*, size_t>::iterator iter = 828 for (std::map<RenderProcessHost*, size_t>::iterator iter =
820 processes.begin(); 829 processes.begin();
821 iter != processes.end(); ++iter) { 830 iter != processes.end(); ++iter) {
822 iter->first->FastShutdownForPageCount(iter->second); 831 iter->first->FastShutdownForPageCount(iter->second);
823 } 832 }
824 } 833 }
825 834
826 // We now return to our regularly scheduled shutdown procedure. 835 // We now return to our regularly scheduled shutdown procedure.
827 for (size_t i = 0; i < indices.size(); ++i) { 836 for (size_t i = 0; i < tabs.size(); ++i) {
828 TabContents* detached_contents = GetContentsAt(indices[i]); 837 TabContents* detached_contents = tabs[i];
838 int index = GetIndexOfTabContents(detached_contents);
839 // Make sure we still contain the tab.
840 if (index == kNoTab)
841 continue;
842
829 detached_contents->OnCloseStarted(); 843 detached_contents->OnCloseStarted();
830 844
831 if (!delegate_->CanCloseContentsAt(indices[i])) { 845 if (!delegate_->CanCloseContentsAt(index)) {
832 retval = false; 846 retval = false;
833 continue; 847 continue;
834 } 848 }
835 849
836 // Update the explicitly closed state. If the unload handlers cancel the 850 // Update the explicitly closed state. If the unload handlers cancel the
837 // close the state is reset in Browser. We don't update the explicitly 851 // close the state is reset in Browser. We don't update the explicitly
838 // closed state if already marked as explicitly closed as unload handlers 852 // closed state if already marked as explicitly closed as unload handlers
839 // call back to this if the close is allowed. 853 // call back to this if the close is allowed.
840 if (!detached_contents->closed_by_user_gesture()) { 854 if (!detached_contents->closed_by_user_gesture()) {
841 detached_contents->set_closed_by_user_gesture( 855 detached_contents->set_closed_by_user_gesture(
842 close_types & CLOSE_USER_GESTURE); 856 close_types & CLOSE_USER_GESTURE);
843 } 857 }
844 858
845 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) { 859 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) {
846 retval = false; 860 retval = false;
847 continue; 861 continue;
848 } 862 }
849 863
850 InternalCloseTab(detached_contents, indices[i], 864 InternalCloseTab(detached_contents, index,
851 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); 865 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0);
852 } 866 }
853 867
854 return retval; 868 return retval;
855 } 869 }
856 870
857 void TabStripModel::InternalCloseTab(TabContents* contents, 871 void TabStripModel::InternalCloseTab(TabContents* contents,
858 int index, 872 int index,
859 bool create_historical_tabs) { 873 bool create_historical_tabs) {
860 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 874 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 938 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
925 TabMoved(moved_data->contents, index, to_position)); 939 TabMoved(moved_data->contents, index, to_position));
926 } 940 }
927 941
928 // static 942 // static
929 bool TabStripModel::OpenerMatches(const TabContentsData* data, 943 bool TabStripModel::OpenerMatches(const TabContentsData* data,
930 const NavigationController* opener, 944 const NavigationController* opener,
931 bool use_group) { 945 bool use_group) {
932 return data->opener == opener || (use_group && data->group == opener); 946 return data->opener == opener || (use_group && data->group == opener);
933 } 947 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/tabs/tab_strip_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698