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/ui/unload_controller.h" | 5 #include "chrome/browser/ui/unload_controller.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 284 |
285 void UnloadController::TabDetachedImpl(content::WebContents* contents) { | 285 void UnloadController::TabDetachedImpl(content::WebContents* contents) { |
286 if (is_attempting_to_close_browser_) | 286 if (is_attempting_to_close_browser_) |
287 ClearUnloadState(contents, false); | 287 ClearUnloadState(contents, false); |
288 registrar_.Remove(this, | 288 registrar_.Remove(this, |
289 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 289 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
290 content::Source<content::WebContents>(contents)); | 290 content::Source<content::WebContents>(contents)); |
291 } | 291 } |
292 | 292 |
293 void UnloadController::ProcessPendingTabs() { | 293 void UnloadController::ProcessPendingTabs() { |
| 294 // Cancel posted/queued ProcessPendingTabs task if there is any. |
| 295 weak_factory_.InvalidateWeakPtrs(); |
| 296 |
294 if (!is_attempting_to_close_browser_) { | 297 if (!is_attempting_to_close_browser_) { |
295 // Because we might invoke this after a delay it's possible for the value of | 298 // Because we might invoke this after a delay it's possible for the value of |
296 // is_attempting_to_close_browser_ to have changed since we scheduled the | 299 // is_attempting_to_close_browser_ to have changed since we scheduled the |
297 // task. | 300 // task. |
298 return; | 301 return; |
299 } | 302 } |
300 | 303 |
301 if (HasCompletedUnloadProcessing()) { | 304 if (HasCompletedUnloadProcessing() && !TabsNeedBeforeUnloadFired()) { |
302 // We've finished all the unload events and can proceed to close the | 305 // We've finished all the unload events and can proceed to close the |
303 // browser. | 306 // browser. |
304 browser_->OnWindowClosing(); | 307 browser_->OnWindowClosing(); |
305 return; | 308 return; |
306 } | 309 } |
307 | 310 |
308 // Process beforeunload tabs first. When that queue is empty, process | 311 // Process beforeunload tabs first. When that queue is empty, process |
309 // unload tabs. | 312 // unload tabs. |
310 if (!tabs_needing_before_unload_fired_.empty()) { | 313 if (!tabs_needing_before_unload_fired_.empty()) { |
311 content::WebContents* web_contents = | 314 content::WebContents* web_contents = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 375 } |
373 | 376 |
374 void UnloadController::ClearUnloadState(content::WebContents* web_contents, | 377 void UnloadController::ClearUnloadState(content::WebContents* web_contents, |
375 bool process_now) { | 378 bool process_now) { |
376 if (is_attempting_to_close_browser_) { | 379 if (is_attempting_to_close_browser_) { |
377 RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); | 380 RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); |
378 RemoveFromSet(&tabs_needing_unload_fired_, web_contents); | 381 RemoveFromSet(&tabs_needing_unload_fired_, web_contents); |
379 if (process_now) { | 382 if (process_now) { |
380 ProcessPendingTabs(); | 383 ProcessPendingTabs(); |
381 } else { | 384 } else { |
| 385 // Do not post a new task if there is already any. |
| 386 if (weak_factory_.HasWeakPtrs()) |
| 387 return; |
382 base::ThreadTaskRunnerHandle::Get()->PostTask( | 388 base::ThreadTaskRunnerHandle::Get()->PostTask( |
383 FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, | 389 FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, |
384 weak_factory_.GetWeakPtr())); | 390 weak_factory_.GetWeakPtr())); |
385 } | 391 } |
386 } | 392 } |
387 } | 393 } |
388 | 394 |
389 } // namespace chrome | 395 } // namespace chrome |
OLD | NEW |