| Index: chrome/browser/sessions/session_service_unittest.cc
|
| diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc
|
| index 082602a35e07bd41517ef20873e568ed9875cd86..37ab3a6bd41014f5bcb9b8241bcc8792ae6aa975 100644
|
| --- a/chrome/browser/sessions/session_service_unittest.cc
|
| +++ b/chrome/browser/sessions/session_service_unittest.cc
|
| @@ -9,9 +9,11 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/memory/scoped_vector.h"
|
| #include "base/path_service.h"
|
| +#include "base/run_loop.h"
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "base/time/time.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/chrome_notification_types.h"
|
| @@ -164,8 +166,6 @@ class SessionServiceTest : public BrowserWithTestWindowTest,
|
|
|
| SessionService* service() { return helper_.service(); }
|
|
|
| - SessionBackend* backend() { return helper_.backend(); }
|
| -
|
| const gfx::Rect window_bounds;
|
|
|
| SessionID window_id;
|
| @@ -999,3 +999,52 @@ TEST_F(SessionServiceTest, IgnoreBlacklistedUrls) {
|
| helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab);
|
| helper_.AssertNavigationEquals(nav1, tab->navigations[0]);
|
| }
|
| +
|
| +// Functions used by GetSessionsAndDestroy.
|
| +namespace {
|
| +
|
| +void OnGotPreviousSession(ScopedVector<SessionWindow> windows,
|
| + SessionID::id_type ignored_active_window) {
|
| + FAIL() << "SessionService was destroyed, this shouldn't be reached.";
|
| +}
|
| +
|
| +void PostBackToThread(base::MessageLoop* message_loop,
|
| + base::RunLoop* run_loop) {
|
| + message_loop->PostTask(FROM_HERE,
|
| + base::Bind(&base::RunLoop::Quit,
|
| + base::Unretained(run_loop)));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Verifies that SessionService::GetLastSession() works correctly if the
|
| +// SessionService is deleted during processing. To verify the problematic case
|
| +// does the following:
|
| +// 1. Sends a task to the background thread that blocks.
|
| +// 2. Asks SessionService for the last session commands. This is blocked by 1.
|
| +// 3. Posts another task to the background thread, this too is blocked by 1.
|
| +// 4. Deletes SessionService.
|
| +// 5. Signals the semaphore that 2 and 3 are waiting on, allowing
|
| +// GetLastSession() to continue.
|
| +// 6. runs the message loop, this is quit when the task scheduled in 3 posts
|
| +// back to the ui thread to quit the run loop.
|
| +// The call to get the previous session should never be invoked because the
|
| +// SessionService was destroyed before SessionService could process the results.
|
| +TEST_F(SessionServiceTest, GetSessionsAndDestroy) {
|
| + base::CancelableTaskTracker cancelable_task_tracker;
|
| + base::RunLoop run_loop;
|
| + base::WaitableEvent event(true, false);
|
| + helper_.RunTaskOnBackendThread(FROM_HERE,
|
| + base::Bind(&base::WaitableEvent::Wait,
|
| + base::Unretained(&event)));
|
| + service()->GetLastSession(base::Bind(&OnGotPreviousSession),
|
| + &cancelable_task_tracker);
|
| + helper_.RunTaskOnBackendThread(
|
| + FROM_HERE,
|
| + base::Bind(&PostBackToThread,
|
| + base::Unretained(base::MessageLoop::current()),
|
| + base::Unretained(&run_loop)));
|
| + delete helper_.ReleaseService();
|
| + event.Signal();
|
| + run_loop.Run();
|
| +}
|
|
|