diff options
Diffstat (limited to 'sync/internal_api')
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.cc | 34 | ||||
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.h | 21 | ||||
-rw-r--r-- | sync/internal_api/public/engine/passive_model_worker.cc | 3 | ||||
-rw-r--r-- | sync/internal_api/public/engine/passive_model_worker.h | 4 | ||||
-rw-r--r-- | sync/internal_api/public/sync_manager.h | 2 | ||||
-rw-r--r-- | sync/internal_api/public/test/fake_sync_manager.h | 2 | ||||
-rw-r--r-- | sync/internal_api/sync_manager_impl.cc | 4 | ||||
-rw-r--r-- | sync/internal_api/sync_manager_impl.h | 2 | ||||
-rw-r--r-- | sync/internal_api/test/fake_sync_manager.cc | 5 |
9 files changed, 61 insertions, 16 deletions
diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc index 44e0a24..7179ed5 100644 --- a/sync/internal_api/public/engine/model_safe_worker.cc +++ b/sync/internal_api/public/engine/model_safe_worker.cc @@ -4,6 +4,7 @@ #include "sync/internal_api/public/engine/model_safe_worker.h" +#include "base/bind.h" #include "base/json/json_writer.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" @@ -84,7 +85,9 @@ std::string ModelSafeGroupToString(ModelSafeGroup group) { ModelSafeWorker::ModelSafeWorker(WorkerLoopDestructionObserver* observer) : stopped_(false), work_done_or_stopped_(false, false), - observer_(observer) {} + observer_(observer), + working_loop_(NULL), + working_loop_set_wait_(true, false) {} ModelSafeWorker::~ModelSafeWorker() {} @@ -135,4 +138,33 @@ void ModelSafeWorker::WillDestroyCurrentMessageLoop() { observer_->OnWorkerLoopDestroyed(GetModelSafeGroup()); } +void ModelSafeWorker::SetWorkingLoopToCurrent() { + DCHECK(!working_loop_); + working_loop_ = base::MessageLoop::current(); + working_loop_set_wait_.Signal(); +} + +void ModelSafeWorker::UnregisterForLoopDestruction( + base::Callback<void(ModelSafeGroup)> unregister_done_callback) { + // Ok to wait until |working_loop_| is set because this is called on sync + // loop. + working_loop_set_wait_.Wait(); + + // Should be called on sync loop. + DCHECK_NE(base::MessageLoop::current(), working_loop_); + DCHECK(working_loop_); + working_loop_->PostTask( + FROM_HERE, + base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync, + this, unregister_done_callback)); +} + +void ModelSafeWorker::UnregisterForLoopDestructionAsync( + base::Callback<void(ModelSafeGroup)> unregister_done_callback) { + DCHECK(stopped_); + DCHECK_EQ(base::MessageLoop::current(), working_loop_); + base::MessageLoop::current()->RemoveDestructionObserver(this); + unregister_done_callback.Run(GetModelSafeGroup()); +} + } // namespace syncer diff --git a/sync/internal_api/public/engine/model_safe_worker.h b/sync/internal_api/public/engine/model_safe_worker.h index aedf649..c7df5a5 100644 --- a/sync/internal_api/public/engine/model_safe_worker.h +++ b/sync/internal_api/public/engine/model_safe_worker.h @@ -69,9 +69,16 @@ class SYNC_EXPORT ModelSafeWorker public base::MessageLoop::DestructionObserver { public: // Subclass should implement to observe destruction of the loop where - // it actually does work. + // it actually does work. Called on UI thread immediately after worker is + // created. virtual void RegisterForLoopDestruction() = 0; + // Called on sync loop from SyncBackendRegistrar::ShutDown(). Post task to + // working loop to stop observing loop destruction and invoke + // |unregister_done_callback|. + virtual void UnregisterForLoopDestruction( + base::Callback<void(ModelSafeGroup)> unregister_done_callback); + // If not stopped, call DoWorkAndWaitUntilDoneImpl() to do work. Otherwise // return CANNOT_DO_WORK. SyncerError DoWorkAndWaitUntilDone(const WorkCallback& work); @@ -103,7 +110,14 @@ class SYNC_EXPORT ModelSafeWorker // Return true if the worker was stopped. Thread safe. bool IsStopped(); + // Subclass should call this in RegisterForLoopDestruction() from the loop + // where work is done. + void SetWorkingLoopToCurrent(); + private: + void UnregisterForLoopDestructionAsync( + base::Callback<void(ModelSafeGroup)> unregister_done_callback); + // Whether the worker should/can do more work. Set when sync is disabled or // when the worker's working thread is to be destroyed. base::Lock stopped_lock_; @@ -115,6 +129,11 @@ class SYNC_EXPORT ModelSafeWorker // Notified when working thread of the worker is to be destroyed. WorkerLoopDestructionObserver* observer_; + + // Remember working loop for posting task to unregister destruction + // observation from sync thread when shutting down sync. + base::MessageLoop* working_loop_; + base::WaitableEvent working_loop_set_wait_; }; // A map that details which ModelSafeGroup each ModelType diff --git a/sync/internal_api/public/engine/passive_model_worker.cc b/sync/internal_api/public/engine/passive_model_worker.cc index 8b1a4e3..eed9fb9 100644 --- a/sync/internal_api/public/engine/passive_model_worker.cc +++ b/sync/internal_api/public/engine/passive_model_worker.cc @@ -18,7 +18,8 @@ PassiveModelWorker::~PassiveModelWorker() { } void PassiveModelWorker::RegisterForLoopDestruction() { - NOTREACHED(); + base::MessageLoop::current()->AddDestructionObserver(this); + SetWorkingLoopToCurrent(); } SyncerError PassiveModelWorker::DoWorkAndWaitUntilDoneImpl( diff --git a/sync/internal_api/public/engine/passive_model_worker.h b/sync/internal_api/public/engine/passive_model_worker.h index f834c83..783731b 100644 --- a/sync/internal_api/public/engine/passive_model_worker.h +++ b/sync/internal_api/public/engine/passive_model_worker.h @@ -11,10 +11,6 @@ #include "sync/internal_api/public/engine/model_safe_worker.h" #include "sync/internal_api/public/util/syncer_error.h" -namespace base { -class MessageLoop; -} - namespace syncer { // Implementation of ModelSafeWorker for passive types. All work is diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index bc6a137..2c2c02d 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -401,7 +401,7 @@ class SYNC_EXPORT SyncManager : public syncer::InvalidationHandler { // If no scheduler exists, the callback is run immediately (from the loop // this was created on, which is the sync loop), as sync is effectively // stopped. - virtual void StopSyncingForShutdown(const base::Closure& callback) = 0; + virtual void StopSyncingForShutdown() = 0; // Issue a final SaveChanges, and close sqlite handles. virtual void ShutdownOnSyncThread() = 0; diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h index ed69a52..38c3d87 100644 --- a/sync/internal_api/public/test/fake_sync_manager.h +++ b/sync/internal_api/public/test/fake_sync_manager.h @@ -115,7 +115,7 @@ class FakeSyncManager : public SyncManager { virtual void RemoveObserver(Observer* observer) OVERRIDE; virtual SyncStatus GetDetailedStatus() const OVERRIDE; virtual void SaveChanges() OVERRIDE; - virtual void StopSyncingForShutdown(const base::Closure& callback) OVERRIDE; + virtual void StopSyncingForShutdown() OVERRIDE; virtual void ShutdownOnSyncThread() OVERRIDE; virtual UserShare* GetUserShare() OVERRIDE; virtual const std::string cache_guid() OVERRIDE; diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 7b0e549..5700fb9 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -620,9 +620,9 @@ void SyncManagerImpl::RemoveObserver(SyncManager::Observer* observer) { observers_.RemoveObserver(observer); } -void SyncManagerImpl::StopSyncingForShutdown(const base::Closure& callback) { +void SyncManagerImpl::StopSyncingForShutdown() { DVLOG(2) << "StopSyncingForShutdown"; - scheduler_->RequestStop(callback); + scheduler_->RequestStop(); if (connection_manager_) connection_manager_->TerminateAllIO(); } diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h index 153df81..1a97d07 100644 --- a/sync/internal_api/sync_manager_impl.h +++ b/sync/internal_api/sync_manager_impl.h @@ -106,7 +106,7 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl : virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE; virtual SyncStatus GetDetailedStatus() const OVERRIDE; virtual void SaveChanges() OVERRIDE; - virtual void StopSyncingForShutdown(const base::Closure& callback) OVERRIDE; + virtual void StopSyncingForShutdown() OVERRIDE; virtual void ShutdownOnSyncThread() OVERRIDE; virtual UserShare* GetUserShare() OVERRIDE; virtual const std::string cache_guid() OVERRIDE; diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc index 7a6d6a4..24c228c 100644 --- a/sync/internal_api/test/fake_sync_manager.cc +++ b/sync/internal_api/test/fake_sync_manager.cc @@ -210,10 +210,7 @@ void FakeSyncManager::SaveChanges() { // Do nothing. } -void FakeSyncManager::StopSyncingForShutdown(const base::Closure& callback) { - if (!sync_task_runner_->PostTask(FROM_HERE, callback)) { - NOTREACHED(); - } +void FakeSyncManager::StopSyncingForShutdown() { } void FakeSyncManager::ShutdownOnSyncThread() { |