diff options
author | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-19 01:17:02 +0000 |
---|---|---|
committer | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-19 01:17:02 +0000 |
commit | ea29851b736ba58190146f5ce0bef59683ad8904 (patch) | |
tree | d5dea3dc7483b2d65601d87304b3282189f3dbb5 /sync/test | |
parent | 4f432a56da54cdbe213ae943944599072a690c75 (diff) | |
download | chromium_src-ea29851b736ba58190146f5ce0bef59683ad8904.zip chromium_src-ea29851b736ba58190146f5ce0bef59683ad8904.tar.gz chromium_src-ea29851b736ba58190146f5ce0bef59683ad8904.tar.bz2 |
sync: Gracefully handle early shutdown
Introduce a new object to communicate cross-thread cancellation signals.
This new object, the CancellationSignal, is protected by a lock. It
allows the receiving thread to query whether or not a stop has been
requested. It also allows the receiving thread to safely register a
cross-thread callback to be invoked immediately when a stop is
requested.
We use two instances of this class to ensure we meet all the
requirements for a safe and fast sync backend shutdown.
The first instance is used with the HttpBridgeFactory to allow the UI
thread to force it to drop all refereces to its RequestContextGetter
immediately. This is an important part of our plan to ensure that all
references to that object are released before
ProfileSyncService::Shutdown() returns, which is necessary to avoid
racy crashes at shutdown. (See crbug.com/236451)
The second instance is used with the ServerConnectionManager and the
Syncer. Once signalled, it ensures that any active connections are
released (possibly decrementing another ref to the
RequestContextGetter), that any blocking I/O is aborted, and that no
more connections will be instantiated. It's important to prevent the
creation of more connections because the HttpBridgeFactory might trigger
a crash if we asked it to create another connection after it had been
shut down.
The syncer's interaction with the second cancelation signal is more
passive. It does not execute any callbacks when the signal is sent.
Instead, it queries the signal as it performs sync cycles, and will cut
short any existing sync cycle if it notices the signal has been sent.
Finally, this CL includes one important change to the initialization of
the HttpBridgeFactory. In order to properly register with the
cancellation signal while still allowing the creation of the user agent
to occur on the sync thread, its initialization had to be split into two
parts. This class now has an Init() method in addition to its
constructor.
BUG=236451
Review URL: https://chromiumcodereview.appspot.com/23717047
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@224014 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/test')
-rw-r--r-- | sync/test/engine/fake_sync_scheduler.cc | 2 | ||||
-rw-r--r-- | sync/test/engine/fake_sync_scheduler.h | 2 | ||||
-rw-r--r-- | sync/test/engine/mock_connection_manager.cc | 5 | ||||
-rw-r--r-- | sync/test/engine/mock_connection_manager.h | 4 | ||||
-rw-r--r-- | sync/test/engine/syncer_command_test.h | 5 |
5 files changed, 12 insertions, 6 deletions
diff --git a/sync/test/engine/fake_sync_scheduler.cc b/sync/test/engine/fake_sync_scheduler.cc index 1e0c7e8..5d45494 100644 --- a/sync/test/engine/fake_sync_scheduler.cc +++ b/sync/test/engine/fake_sync_scheduler.cc @@ -13,7 +13,7 @@ FakeSyncScheduler::~FakeSyncScheduler() {} void FakeSyncScheduler::Start(Mode mode) { } -void FakeSyncScheduler::RequestStop() { +void FakeSyncScheduler::Stop() { } void FakeSyncScheduler::ScheduleLocalNudge( diff --git a/sync/test/engine/fake_sync_scheduler.h b/sync/test/engine/fake_sync_scheduler.h index 11a63cc..95bdfa9 100644 --- a/sync/test/engine/fake_sync_scheduler.h +++ b/sync/test/engine/fake_sync_scheduler.h @@ -20,7 +20,7 @@ class FakeSyncScheduler : public SyncScheduler { virtual ~FakeSyncScheduler(); virtual void Start(Mode mode) OVERRIDE; - virtual void RequestStop() OVERRIDE; + virtual void Stop() OVERRIDE; virtual void ScheduleLocalNudge( const base::TimeDelta& desired_delay, ModelTypeSet types, diff --git a/sync/test/engine/mock_connection_manager.cc b/sync/test/engine/mock_connection_manager.cc index 5bf2b4b..009b5a1 100644 --- a/sync/test/engine/mock_connection_manager.cc +++ b/sync/test/engine/mock_connection_manager.cc @@ -33,8 +33,9 @@ using syncable::WriteTransaction; static char kValidAuthToken[] = "AuthToken"; static char kCacheGuid[] = "kqyg7097kro6GSUod+GSg=="; -MockConnectionManager::MockConnectionManager(syncable::Directory* directory) - : ServerConnectionManager("unused", 0, false, false), +MockConnectionManager::MockConnectionManager(syncable::Directory* directory, + CancelationSignal* signal) + : ServerConnectionManager("unused", 0, false, false, signal), server_reachable_(true), conflict_all_commits_(false), conflict_n_commits_(0), diff --git a/sync/test/engine/mock_connection_manager.h b/sync/test/engine/mock_connection_manager.h index 83de59a..afeaac8 100644 --- a/sync/test/engine/mock_connection_manager.h +++ b/sync/test/engine/mock_connection_manager.h @@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_vector.h" +#include "base/synchronization/lock.h" #include "sync/engine/net/server_connection_manager.h" #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/base/unique_position.h" @@ -32,7 +33,8 @@ class MockConnectionManager : public ServerConnectionManager { virtual ~MidCommitObserver() {} }; - explicit MockConnectionManager(syncable::Directory*); + MockConnectionManager(syncable::Directory*, + CancelationSignal* signal); virtual ~MockConnectionManager(); // Overridden ServerConnectionManager functions. diff --git a/sync/test/engine/syncer_command_test.h b/sync/test/engine/syncer_command_test.h index 6e1f672..28e3207 100644 --- a/sync/test/engine/syncer_command_test.h +++ b/sync/test/engine/syncer_command_test.h @@ -15,6 +15,7 @@ #include "sync/engine/model_changing_syncer_command.h" #include "sync/engine/traffic_recorder.h" #include "sync/internal_api/debug_info_event_listener.h" +#include "sync/internal_api/public/base/cancelation_signal.h" #include "sync/internal_api/public/engine/model_safe_worker.h" #include "sync/sessions/debug_info_getter.h" #include "sync/sessions/sync_session.h" @@ -104,7 +105,8 @@ class SyncerCommandTestBase : public testing::Test, // Install a MockServerConnection. Resets the context. By default, // the context does not have a MockServerConnection attached. void ConfigureMockServerConnection() { - mock_server_.reset(new MockConnectionManager(directory())); + mock_server_.reset(new MockConnectionManager(directory(), + &cancelation_signal_)); ResetContext(); } @@ -169,6 +171,7 @@ class SyncerCommandTestBase : public testing::Test, DebugInfoEventListener debug_info_event_listener_; scoped_refptr<ExtensionsActivity> extensions_activity_; TrafficRecorder traffic_recorder_; + CancelationSignal cancelation_signal_; DISALLOW_COPY_AND_ASSIGN(SyncerCommandTestBase); }; |