Index: chrome/browser/win/jumplist.cc |
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc |
index 59377fbee9fd99d9f1bbbf9b8f9c3ca01883a3ea..4106cac4c547234f117536400c45915c61afe4e0 100644 |
--- a/chrome/browser/win/jumplist.cc |
+++ b/chrome/browser/win/jumplist.cc |
@@ -64,15 +64,28 @@ using JumpListData = JumpList::JumpListData; |
namespace { |
+// The maximum allowed number of updates that can be cancelled intentionally due |
+// to one jumplist updater timeout. |
+constexpr int kCancelledUpdates = 10; |
gab
2017/05/11 14:48:24
Feels like we should delay for a period of time, e
chengx
2017/05/11 16:41:43
I did think about delaying for a period of time. B
|
+ |
// The delay before updating the JumpList to prevent update storms. |
constexpr base::TimeDelta kDelayForJumplistUpdate = |
base::TimeDelta::FromMilliseconds(3500); |
// The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking |
// longer than this are discarded to prevent bogging down slow machines. |
-constexpr base::TimeDelta kTimeOutForJumplistUpdate = |
+constexpr base::TimeDelta kTimeOutForJumplistBeginUpdate = |
+ base::TimeDelta::FromMilliseconds(500); |
+ |
+// The maximum allowed time for updating both "most visited" and "recently |
+// closed" categories via JumpListUpdater::AddCustomCategory. |
+constexpr base::TimeDelta kTimeOutForAddCustomCategory = |
base::TimeDelta::FromMilliseconds(500); |
+// The maximum allowed time for JumpListUpdater::CommitUpdate. |
+constexpr base::TimeDelta kTimeOutForJumplistCommitUpdate = |
+ base::TimeDelta::FromMilliseconds(1000); |
+ |
// Appends the common switches to each shell link. |
void AppendCommonSwitches(ShellLinkItem* shell_link) { |
const char* kSwitchNames[] = { switches::kUserDataDir }; |
@@ -190,6 +203,8 @@ JumpList::JumpList(Profile* profile) |
: RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread( |
content::BrowserThread::UI)), |
profile_(profile), |
+ cancelled_update_count_(0), |
+ jumplist_updater_timeout_(false), |
jumplist_data_(new base::RefCountedData<JumpListData>), |
task_id_(base::CancelableTaskTracker::kBadTaskId), |
update_jumplist_task_runner_(base::CreateCOMSTATaskRunnerWithTraits( |
@@ -522,7 +537,19 @@ void JumpList::TopSitesChanged(history::TopSites* top_sites, |
} |
} |
+bool JumpList::CheckAndUpdateTimeoutInfo() { |
+ if (jumplist_updater_timeout_ && |
+ ++cancelled_update_count_ > kCancelledUpdates) { |
+ jumplist_updater_timeout_ = false; |
+ cancelled_update_count_ = 0; |
+ } |
+ return jumplist_updater_timeout_; |
+} |
+ |
void JumpList::DeferredTopSitesChanged() { |
+ if (CheckAndUpdateTimeoutInfo()) |
+ return; |
+ |
scoped_refptr<history::TopSites> top_sites = |
TopSitesFactory::GetForProfile(profile_); |
if (top_sites) { |
@@ -534,6 +561,9 @@ void JumpList::DeferredTopSitesChanged() { |
} |
void JumpList::DeferredTabRestoreServiceChanged() { |
+ if (CheckAndUpdateTimeoutInfo()) |
+ return; |
+ |
// Create a list of ShellLinkItems from the "Recently Closed" pages. |
// As noted above, we create a ShellLinkItem objects with the following |
// parameters. |
@@ -620,8 +650,10 @@ bool JumpList::UpdateJumpList( |
// Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer |
// than the maximum allowed time, as it's very likely the following update |
// steps will also take a long time. |
- if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate) |
+ if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { |
+ jumplist_updater_timeout_ = true; |
return false; |
+ } |
// The default maximum number of items to display in JumpList is 10. |
// https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx |
@@ -686,6 +718,8 @@ bool JumpList::UpdateJumpList( |
// TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); |
+ base::ElapsedTimer add_custom_category_timer; |
+ |
// Update the "Most Visited" category of the JumpList if it exists. |
// This update request is applied into the JumpList when we commit this |
// transaction. |
@@ -702,12 +736,26 @@ bool JumpList::UpdateJumpList( |
return false; |
} |
+ // If JumpListUpdater::AddCustomCategory takes longer than the maximum allowed |
+ // time, mark the flag but continue with this update. |
+ if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) |
+ jumplist_updater_timeout_ = true; |
+ |
// Update the "Tasks" category of the JumpList. |
if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
return false; |
+ base::ElapsedTimer commit_update_timer; |
+ |
// Commit this transaction and send the updated JumpList to Windows. |
- return jumplist_updater.CommitUpdate(); |
+ bool commit_result = jumplist_updater.CommitUpdate(); |
+ |
+ // If JumpListUpdater::CommitUpdate takes longer than the maximum allowed |
+ // time, mark the flag but continue with this update. |
+ if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) |
+ jumplist_updater_timeout_ = true; |
+ |
+ return commit_result; |
} |
void JumpList::RunUpdateJumpList( |