Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(545)

Side by Side Diff: chrome/browser/sync/engine/syncapi.cc

Issue 7044059: [Sync] Ensure all accesses to SyncInternal's observers are thread safe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/valgrind/tsan/suppressions.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/sync/engine/syncapi.h" 5 #include "chrome/browser/sync/engine/syncapi.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <bitset> 8 #include <bitset>
9 #include <iomanip> 9 #include <iomanip>
10 #include <list> 10 #include <list>
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 1230
1231 // SyncNotifierObserver implementation. 1231 // SyncNotifierObserver implementation.
1232 virtual void OnNotificationStateChange( 1232 virtual void OnNotificationStateChange(
1233 bool notifications_enabled); 1233 bool notifications_enabled);
1234 1234
1235 virtual void OnIncomingNotification( 1235 virtual void OnIncomingNotification(
1236 const syncable::ModelTypePayloadMap& type_payloads); 1236 const syncable::ModelTypePayloadMap& type_payloads);
1237 1237
1238 virtual void StoreState(const std::string& cookie); 1238 virtual void StoreState(const std::string& cookie);
1239 1239
1240 bool HaveObservers();
akalin 2011/06/08 22:39:38 make const
Nicolas Zea 2011/06/08 23:10:23 Done.
1241
1240 void AddObserver(SyncManager::Observer* observer); 1242 void AddObserver(SyncManager::Observer* observer);
1241 1243
1242 void RemoveObserver(SyncManager::Observer* observer); 1244 void RemoveObserver(SyncManager::Observer* observer);
1243 1245
1244 // Accessors for the private members. 1246 // Accessors for the private members.
1245 DirectoryManager* dir_manager() { return share_.dir_manager.get(); } 1247 DirectoryManager* dir_manager() { return share_.dir_manager.get(); }
1246 SyncAPIServerConnectionManager* connection_manager() { 1248 SyncAPIServerConnectionManager* connection_manager() {
1247 return connection_manager_.get(); 1249 return connection_manager_.get();
1248 } 1250 }
1249 SyncerThread* syncer_thread() { return syncer_thread_.get(); } 1251 SyncerThread* syncer_thread() { return syncer_thread_.get(); }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 browser_sync::JsArgList FindNodesContainingString( 1522 browser_sync::JsArgList FindNodesContainingString(
1521 const browser_sync::JsArgList& args); 1523 const browser_sync::JsArgList& args);
1522 1524
1523 // We couple the DirectoryManager and username together in a UserShare member 1525 // We couple the DirectoryManager and username together in a UserShare member
1524 // so we can return a handle to share_ to clients of the API for use when 1526 // so we can return a handle to share_ to clients of the API for use when
1525 // constructing any transaction type. 1527 // constructing any transaction type.
1526 UserShare share_; 1528 UserShare share_;
1527 1529
1528 MessageLoop* core_message_loop_; 1530 MessageLoop* core_message_loop_;
1529 1531
1532 // We have to lock around every observers_ access because it can get accessed
1533 // from any thread and added to/removed from on the core thread.
1534 base::Lock observers_lock_;
akalin 2011/06/08 22:39:38 make mutable
Nicolas Zea 2011/06/08 23:10:23 Done.
1530 ObserverList<SyncManager::Observer> observers_; 1535 ObserverList<SyncManager::Observer> observers_;
1531 1536
1532 browser_sync::JsEventRouter* parent_router_; 1537 browser_sync::JsEventRouter* parent_router_;
1533 1538
1534 // The ServerConnectionManager used to abstract communication between the 1539 // The ServerConnectionManager used to abstract communication between the
1535 // client (the Syncer) and the sync server. 1540 // client (the Syncer) and the sync server.
1536 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; 1541 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_;
1537 1542
1538 // The thread that runs the Syncer. Needs to be explicitly Start()ed. 1543 // The thread that runs the Syncer. Needs to be explicitly Start()ed.
1539 scoped_ptr<SyncerThread> syncer_thread_; 1544 scoped_ptr<SyncerThread> syncer_thread_;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 // Map used to store the notification info to be displayed in about:sync page. 1586 // Map used to store the notification info to be displayed in about:sync page.
1582 NotificationInfoMap notification_info_map_; 1587 NotificationInfoMap notification_info_map_;
1583 1588
1584 browser_sync::JsDirectoryChangeListener js_directory_change_listener_; 1589 browser_sync::JsDirectoryChangeListener js_directory_change_listener_;
1585 1590
1586 JsMessageHandlerMap js_message_handlers_; 1591 JsMessageHandlerMap js_message_handlers_;
1587 }; 1592 };
1588 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200; 1593 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200;
1589 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000; 1594 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000;
1590 1595
1596 // We have to read the current observer list while holding a lock because it
1597 // can be added/removed from another thread. We then notify the actual observers
1598 // while the lock is released.
akalin 2011/06/08 22:39:38 Add a TODO explaining the problem with notifying g
Nicolas Zea 2011/06/08 23:10:23 Done.
1599 #define NOTIFY_SYNCMANAGER_OBSERVERS(function) \
akalin 2011/06/08 22:39:38 I think it would be cleaner to define a utility fu
Nicolas Zea 2011/06/08 23:10:23 Done.
1600 do { \
1601 ObserverList<SyncManager::Observer> temp_observers; \
1602 { \
1603 base::AutoLock lock(observers_lock_); \
1604 ObserverListBase<SyncManager::Observer>::Iterator it(observers_); \
1605 SyncManager::Observer* obs; \
1606 while ((obs = it.GetNext()) != NULL) \
1607 temp_observers.AddObserver(obs); \
1608 } \
1609 FOR_EACH_OBSERVER(SyncManager::Observer, temp_observers, function); \
1610 } while (0)
1611
1591 SyncManager::Observer::~Observer() {} 1612 SyncManager::Observer::~Observer() {}
1592 1613
1593 SyncManager::SyncManager() { 1614 SyncManager::SyncManager() {
1594 data_ = new SyncInternal(this); 1615 data_ = new SyncInternal(this);
1595 } 1616 }
1596 1617
1597 bool SyncManager::Init(const FilePath& database_location, 1618 bool SyncManager::Init(const FilePath& database_location,
1598 const char* sync_server_and_path, 1619 const char* sync_server_and_path,
1599 int sync_server_port, 1620 int sync_server_port,
1600 bool use_ssl, 1621 bool use_ssl,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 1822
1802 ReadNode node(&trans); 1823 ReadNode node(&trans);
1803 if (!node.InitByTagLookup(kNigoriTag)) { 1824 if (!node.InitByTagLookup(kNigoriTag)) {
1804 NOTREACHED(); 1825 NOTREACHED();
1805 return; 1826 return;
1806 } 1827 }
1807 1828
1808 nigori.CopyFrom(node.GetNigoriSpecifics()); 1829 nigori.CopyFrom(node.GetNigoriSpecifics());
1809 Cryptographer::UpdateResult result = cryptographer->Update(nigori); 1830 Cryptographer::UpdateResult result = cryptographer->Update(nigori);
1810 if (result == Cryptographer::NEEDS_PASSPHRASE) { 1831 if (result == Cryptographer::NEEDS_PASSPHRASE) {
1811 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1832 NOTIFY_SYNCMANAGER_OBSERVERS(
1812 OnPassphraseRequired(sync_api::REASON_DECRYPTION)); 1833 OnPassphraseRequired(sync_api::REASON_DECRYPTION));
1813 } 1834 }
1814 1835
1815 // Refresh list of encrypted datatypes. 1836 // Refresh list of encrypted datatypes.
1816 encrypted_types = GetEncryptedTypes(&trans); 1837 encrypted_types = GetEncryptedTypes(&trans);
1817 } 1838 }
1818 1839
1819 1840
1820 1841
1821 // Ensure any datatypes that need encryption are encrypted. 1842 // Ensure any datatypes that need encryption are encrypted.
1822 EncryptDataTypes(encrypted_types); 1843 EncryptDataTypes(encrypted_types);
1823 } 1844 }
1824 1845
1825 void SyncManager::SyncInternal::StartSyncingNormally() { 1846 void SyncManager::SyncInternal::StartSyncingNormally() {
1826 // Start the syncer thread. This won't actually 1847 // Start the syncer thread. This won't actually
1827 // result in any syncing until at least the 1848 // result in any syncing until at least the
1828 // DirectoryManager broadcasts the OPENED event, 1849 // DirectoryManager broadcasts the OPENED event,
1829 // and a valid server connection is detected. 1850 // and a valid server connection is detected.
1830 if (syncer_thread()) // NULL during certain unittests. 1851 if (syncer_thread()) // NULL during certain unittests.
1831 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL); 1852 syncer_thread()->Start(SyncerThread::NORMAL_MODE, NULL);
1832 } 1853 }
1833 1854
1834 void SyncManager::SyncInternal::MarkAndNotifyInitializationComplete() { 1855 void SyncManager::SyncInternal::MarkAndNotifyInitializationComplete() {
1835 // There is only one real time we need this mutex. If we get an auth 1856 // There is only one real time we need this mutex. If we get an auth
1836 // success, and before the initial sync ends we get an auth failure. In this 1857 // success, and before the initial sync ends we get an auth failure. In this
1837 // case we'll be listening to both the AuthWatcher and Syncer, and it's a race 1858 // case we'll be listening to both the AuthWatcher and Syncer, and it's a race
1838 // between their respective threads to call MarkAndNotify. We need to make 1859 // between their respective threads to call MarkAndNotify. We need to make
1839 // sure the observer is notified once and only once. 1860 // sure the observer is notified once and only once.
1840 { 1861 {
1841 base::AutoLock lock(initialized_mutex_); 1862 base::AutoLock lock(initialized_mutex_);
1842 if (initialized_) 1863 if (initialized_)
1843 return; 1864 return;
1844 initialized_ = true; 1865 initialized_ = true;
1845 } 1866 }
1846 1867
1847 // Notify that initialization is complete. 1868 // Notify that initialization is complete.
1848 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1869 NOTIFY_SYNCMANAGER_OBSERVERS(OnInitializationComplete());
1849 OnInitializationComplete());
1850 } 1870 }
1851 1871
1852 void SyncManager::SyncInternal::SendNotification() { 1872 void SyncManager::SyncInternal::SendNotification() {
1853 DCHECK_EQ(MessageLoop::current(), core_message_loop_); 1873 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
1854 if (!sync_notifier_) { 1874 if (!sync_notifier_) {
1855 VLOG(1) << "Not sending notification: sync_notifier_ is NULL"; 1875 VLOG(1) << "Not sending notification: sync_notifier_ is NULL";
1856 return; 1876 return;
1857 } 1877 }
1858 sync_notifier_->SendNotification(); 1878 sync_notifier_->SendNotification();
1859 } 1879 }
1860 1880
1861 bool SyncManager::SyncInternal::OpenDirectory() { 1881 bool SyncManager::SyncInternal::OpenDirectory() {
1862 DCHECK(!initialized()) << "Should only happen once"; 1882 DCHECK(!initialized()) << "Should only happen once";
1863 1883
1864 bool share_opened = dir_manager()->Open(username_for_share()); 1884 bool share_opened = dir_manager()->Open(username_for_share());
1865 DCHECK(share_opened); 1885 DCHECK(share_opened);
1866 if (!share_opened) { 1886 if (!share_opened) {
1867 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1887 NOTIFY_SYNCMANAGER_OBSERVERS(OnStopSyncingPermanently());
1868 OnStopSyncingPermanently());
1869 1888
1870 LOG(ERROR) << "Could not open share for:" << username_for_share(); 1889 LOG(ERROR) << "Could not open share for:" << username_for_share();
1871 return false; 1890 return false;
1872 } 1891 }
1873 1892
1874 // Database has to be initialized for the guid to be available. 1893 // Database has to be initialized for the guid to be available.
1875 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); 1894 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
1876 if (!lookup.good()) { 1895 if (!lookup.good()) {
1877 NOTREACHED(); 1896 NOTREACHED();
1878 return false; 1897 return false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 registrar_->GetModelSafeRoutingInfo(&routes); 1961 registrar_->GetModelSafeRoutingInfo(&routes);
1943 syncable::ModelTypeSet enabled_types; 1962 syncable::ModelTypeSet enabled_types;
1944 for (ModelSafeRoutingInfo::const_iterator it = routes.begin(); 1963 for (ModelSafeRoutingInfo::const_iterator it = routes.begin();
1945 it != routes.end(); ++it) { 1964 it != routes.end(); ++it) {
1946 enabled_types.insert(it->first); 1965 enabled_types.insert(it->first);
1947 } 1966 }
1948 sync_notifier_->UpdateEnabledTypes(enabled_types); 1967 sync_notifier_->UpdateEnabledTypes(enabled_types);
1949 } 1968 }
1950 1969
1951 void SyncManager::SyncInternal::RaiseAuthNeededEvent() { 1970 void SyncManager::SyncInternal::RaiseAuthNeededEvent() {
1952 FOR_EACH_OBSERVER( 1971 NOTIFY_SYNCMANAGER_OBSERVERS(
1953 SyncManager::Observer, observers_,
1954 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS))); 1972 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS)));
1955 } 1973 }
1956 1974
1957 void SyncManager::SyncInternal::SetUsingExplicitPassphrasePrefForMigration( 1975 void SyncManager::SyncInternal::SetUsingExplicitPassphrasePrefForMigration(
1958 WriteTransaction* const trans) { 1976 WriteTransaction* const trans) {
1959 WriteNode node(trans); 1977 WriteNode node(trans);
1960 if (!node.InitByTagLookup(kNigoriTag)) { 1978 if (!node.InitByTagLookup(kNigoriTag)) {
1961 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1979 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1962 NOTREACHED(); 1980 NOTREACHED();
1963 return; 1981 return;
1964 } 1982 }
1965 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics()); 1983 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics());
1966 specifics.set_using_explicit_passphrase(true); 1984 specifics.set_using_explicit_passphrase(true);
1967 node.SetNigoriSpecifics(specifics); 1985 node.SetNigoriSpecifics(specifics);
1968 } 1986 }
1969 1987
1970 void SyncManager::SyncInternal::SetPassphrase( 1988 void SyncManager::SyncInternal::SetPassphrase(
1971 const std::string& passphrase, bool is_explicit) { 1989 const std::string& passphrase, bool is_explicit) {
1972 // We do not accept empty passphrases. 1990 // We do not accept empty passphrases.
1973 if (passphrase.empty()) { 1991 if (passphrase.empty()) {
1974 VLOG(1) << "Rejecting empty passphrase."; 1992 VLOG(1) << "Rejecting empty passphrase.";
1975 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1993 NOTIFY_SYNCMANAGER_OBSERVERS(
1976 OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED)); 1994 OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED));
1977 return; 1995 return;
1978 } 1996 }
1979 1997
1980 // All accesses to the cryptographer are protected by a transaction. 1998 // All accesses to the cryptographer are protected by a transaction.
1981 WriteTransaction trans(GetUserShare()); 1999 WriteTransaction trans(GetUserShare());
1982 Cryptographer* cryptographer = trans.GetCryptographer(); 2000 Cryptographer* cryptographer = trans.GetCryptographer();
1983 KeyParams params = {"localhost", "dummy", passphrase}; 2001 KeyParams params = {"localhost", "dummy", passphrase};
1984 2002
1985 if (cryptographer->has_pending_keys()) { 2003 if (cryptographer->has_pending_keys()) {
1986 if (!cryptographer->DecryptPendingKeys(params)) { 2004 if (!cryptographer->DecryptPendingKeys(params)) {
1987 VLOG(1) << "Passphrase failed to decrypt pending keys."; 2005 VLOG(1) << "Passphrase failed to decrypt pending keys.";
1988 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2006 NOTIFY_SYNCMANAGER_OBSERVERS(
1989 OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED)); 2007 OnPassphraseRequired(sync_api::REASON_SET_PASSPHRASE_FAILED));
1990 return; 2008 return;
1991 } 2009 }
1992 2010
1993 // TODO(tim): If this is the first time the user has entered a passphrase 2011 // TODO(tim): If this is the first time the user has entered a passphrase
1994 // since the protocol changed to store passphrase preferences in the cloud, 2012 // since the protocol changed to store passphrase preferences in the cloud,
1995 // make sure we update this preference. See bug 62103. 2013 // make sure we update this preference. See bug 62103.
1996 // TODO(jhawkins): Verify that this logic may be removed now that the 2014 // TODO(jhawkins): Verify that this logic may be removed now that the
1997 // migration is no longer supported. 2015 // migration is no longer supported.
1998 if (is_explicit) 2016 if (is_explicit)
(...skipping 25 matching lines...) Expand all
2024 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics()); 2042 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics());
2025 specifics.clear_encrypted(); 2043 specifics.clear_encrypted();
2026 cryptographer->GetKeys(specifics.mutable_encrypted()); 2044 cryptographer->GetKeys(specifics.mutable_encrypted());
2027 specifics.set_using_explicit_passphrase(is_explicit); 2045 specifics.set_using_explicit_passphrase(is_explicit);
2028 node.SetNigoriSpecifics(specifics); 2046 node.SetNigoriSpecifics(specifics);
2029 ReEncryptEverything(&trans); 2047 ReEncryptEverything(&trans);
2030 } 2048 }
2031 2049
2032 std::string bootstrap_token; 2050 std::string bootstrap_token;
2033 cryptographer->GetBootstrapToken(&bootstrap_token); 2051 cryptographer->GetBootstrapToken(&bootstrap_token);
2034 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2052 NOTIFY_SYNCMANAGER_OBSERVERS(OnPassphraseAccepted(bootstrap_token));
2035 OnPassphraseAccepted(bootstrap_token));
2036 } 2053 }
2037 2054
2038 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() { 2055 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() {
2039 ReadTransaction trans(&share_); 2056 ReadTransaction trans(&share_);
2040 ReadNode node(&trans); 2057 ReadNode node(&trans);
2041 if (!node.InitByTagLookup(kNigoriTag)) { 2058 if (!node.InitByTagLookup(kNigoriTag)) {
2042 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 2059 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
2043 NOTREACHED(); 2060 NOTREACHED();
2044 return false; 2061 return false;
2045 } 2062 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 WriteNode child(trans); 2160 WriteNode child(trans);
2144 if (!child.InitByIdLookup(child_id)) { 2161 if (!child.InitByIdLookup(child_id)) {
2145 NOTREACHED(); 2162 NOTREACHED();
2146 return; 2163 return;
2147 } 2164 }
2148 child.SetPasswordSpecifics(child.GetPasswordSpecifics()); 2165 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
2149 child_id = child.GetSuccessorId(); 2166 child_id = child.GetSuccessorId();
2150 } 2167 }
2151 } 2168 }
2152 2169
2153 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2170 NOTIFY_SYNCMANAGER_OBSERVERS(OnEncryptionComplete(encrypted_types));
2154 OnEncryptionComplete(encrypted_types));
2155 } 2171 }
2156 2172
2157 SyncManager::~SyncManager() { 2173 SyncManager::~SyncManager() {
2158 delete data_; 2174 delete data_;
2159 } 2175 }
2160 2176
2161 void SyncManager::AddObserver(Observer* observer) { 2177 void SyncManager::AddObserver(Observer* observer) {
2162 data_->AddObserver(observer); 2178 data_->AddObserver(observer);
2163 } 2179 }
2164 2180
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 // TODO(akalin): CheckServerReachable() can block, which may cause 2253 // TODO(akalin): CheckServerReachable() can block, which may cause
2238 // jank if we try to shut down sync. Fix this. 2254 // jank if we try to shut down sync. Fix this.
2239 connection_manager()->CheckServerReachable(); 2255 connection_manager()->CheckServerReachable();
2240 } 2256 }
2241 2257
2242 void SyncManager::SyncInternal::OnServerConnectionEvent( 2258 void SyncManager::SyncInternal::OnServerConnectionEvent(
2243 const ServerConnectionEvent& event) { 2259 const ServerConnectionEvent& event) {
2244 allstatus_.HandleServerConnectionEvent(event); 2260 allstatus_.HandleServerConnectionEvent(event);
2245 if (event.connection_code == 2261 if (event.connection_code ==
2246 browser_sync::HttpResponse::SERVER_CONNECTION_OK) { 2262 browser_sync::HttpResponse::SERVER_CONNECTION_OK) {
2247 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2263 NOTIFY_SYNCMANAGER_OBSERVERS(OnAuthError(AuthError::None()));
2248 OnAuthError(AuthError::None()));
2249 } 2264 }
2250 2265
2251 if (event.connection_code == browser_sync::HttpResponse::SYNC_AUTH_ERROR) { 2266 if (event.connection_code == browser_sync::HttpResponse::SYNC_AUTH_ERROR) {
2252 FOR_EACH_OBSERVER( 2267 NOTIFY_SYNCMANAGER_OBSERVERS(
2253 SyncManager::Observer, observers_,
2254 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS))); 2268 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS)));
2255 } 2269 }
2256 } 2270 }
2257 2271
2258 void SyncManager::SyncInternal::HandleTransactionCompleteChangeEvent( 2272 void SyncManager::SyncInternal::HandleTransactionCompleteChangeEvent(
2259 const syncable::ModelTypeBitSet& models_with_changes) { 2273 const syncable::ModelTypeBitSet& models_with_changes) {
2260 // This notification happens immediately after the transaction mutex is 2274 // This notification happens immediately after the transaction mutex is
2261 // released. This allows work to be performed without blocking other threads 2275 // released. This allows work to be performed without blocking other threads
2262 // from acquiring a transaction. 2276 // from acquiring a transaction.
2263 if (observers_.size() <= 0) 2277 if (!HaveObservers())
2264 return; 2278 return;
2265 2279
2266 // Call commit. 2280 // Call commit.
2267 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) { 2281 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
2268 if (models_with_changes.test(i)) { 2282 if (models_with_changes.test(i)) {
2269 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2283 NOTIFY_SYNCMANAGER_OBSERVERS(
2270 OnChangesComplete(syncable::ModelTypeFromInt(i))); 2284 OnChangesComplete(syncable::ModelTypeFromInt(i)));
2271 } 2285 }
2272 } 2286 }
2273 } 2287 }
2274 2288
2275 ModelTypeBitSet SyncManager::SyncInternal::HandleTransactionEndingChangeEvent( 2289 ModelTypeBitSet SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
2276 syncable::BaseTransaction* trans) { 2290 syncable::BaseTransaction* trans) {
2277 // This notification happens immediately before a syncable WriteTransaction 2291 // This notification happens immediately before a syncable WriteTransaction
2278 // falls out of scope. It happens while the channel mutex is still held, 2292 // falls out of scope. It happens while the channel mutex is still held,
2279 // and while the transaction mutex is held, so it cannot be re-entrant. 2293 // and while the transaction mutex is held, so it cannot be re-entrant.
2280 if (observers_.size() <= 0 || ChangeBuffersAreEmpty()) 2294 if (!HaveObservers() || ChangeBuffersAreEmpty())
2281 return ModelTypeBitSet(); 2295 return ModelTypeBitSet();
2282 2296
2283 // This will continue the WriteTransaction using a read only wrapper. 2297 // This will continue the WriteTransaction using a read only wrapper.
2284 // This is the last chance for read to occur in the WriteTransaction 2298 // This is the last chance for read to occur in the WriteTransaction
2285 // that's closing. This special ReadTransaction will not close the 2299 // that's closing. This special ReadTransaction will not close the
2286 // underlying transaction. 2300 // underlying transaction.
2287 ReadTransaction read_trans(GetUserShare(), trans); 2301 ReadTransaction read_trans(GetUserShare(), trans);
2288 2302
2289 syncable::ModelTypeBitSet models_with_changes; 2303 syncable::ModelTypeBitSet models_with_changes;
2290 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) { 2304 for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) {
2291 if (change_buffers_[i].IsEmpty()) 2305 if (change_buffers_[i].IsEmpty())
2292 continue; 2306 continue;
2293 2307
2294 vector<ChangeRecord> ordered_changes; 2308 vector<ChangeRecord> ordered_changes;
2295 change_buffers_[i].GetAllChangesInTreeOrder(&read_trans, &ordered_changes); 2309 change_buffers_[i].GetAllChangesInTreeOrder(&read_trans, &ordered_changes);
2296 if (!ordered_changes.empty()) { 2310 if (!ordered_changes.empty()) {
2297 FOR_EACH_OBSERVER( 2311 NOTIFY_SYNCMANAGER_OBSERVERS(
2298 SyncManager::Observer, observers_,
2299 OnChangesApplied(syncable::ModelTypeFromInt(i), &read_trans, 2312 OnChangesApplied(syncable::ModelTypeFromInt(i), &read_trans,
2300 &ordered_changes[0], ordered_changes.size())); 2313 &ordered_changes[0], ordered_changes.size()));
2301 models_with_changes.set(i, true); 2314 models_with_changes.set(i, true);
2302 } 2315 }
2303 change_buffers_[i].Clear(); 2316 change_buffers_[i].Clear();
2304 } 2317 }
2305 return models_with_changes; 2318 return models_with_changes;
2306 } 2319 }
2307 2320
2308 void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncApi( 2321 void SyncManager::SyncInternal::HandleCalculateChangesChangeEventFromSyncApi(
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 void SyncManager::SyncInternal::RequestNudgeWithDataTypes( 2450 void SyncManager::SyncInternal::RequestNudgeWithDataTypes(
2438 const TimeDelta& delay, 2451 const TimeDelta& delay,
2439 browser_sync::NudgeSource source, const ModelTypeBitSet& types, 2452 browser_sync::NudgeSource source, const ModelTypeBitSet& types,
2440 const tracked_objects::Location& nudge_location) { 2453 const tracked_objects::Location& nudge_location) {
2441 if (syncer_thread()) 2454 if (syncer_thread())
2442 syncer_thread()->ScheduleNudge(delay, source, types, nudge_location); 2455 syncer_thread()->ScheduleNudge(delay, source, types, nudge_location);
2443 } 2456 }
2444 2457
2445 void SyncManager::SyncInternal::OnSyncEngineEvent( 2458 void SyncManager::SyncInternal::OnSyncEngineEvent(
2446 const SyncEngineEvent& event) { 2459 const SyncEngineEvent& event) {
2447 if (observers_.size() <= 0) { 2460 if (!HaveObservers()) {
2448 VLOG(0) << "OnSyncEngineEvent returning because observers_.size() is zero"; 2461 VLOG(0) << "OnSyncEngineEvent returning because observers_.size() is zero";
2449 return; 2462 return;
2450 } 2463 }
2451 2464
2452 // Only send an event if this is due to a cycle ending and this cycle 2465 // Only send an event if this is due to a cycle ending and this cycle
2453 // concludes a canonical "sync" process; that is, based on what is known 2466 // concludes a canonical "sync" process; that is, based on what is known
2454 // locally we are "all happy" and up-to-date. There may be new changes on 2467 // locally we are "all happy" and up-to-date. There may be new changes on
2455 // the server, but we'll get them on a subsequent sync. 2468 // the server, but we'll get them on a subsequent sync.
2456 // 2469 //
2457 // Notifications are sent at the end of every sync cycle, regardless of 2470 // Notifications are sent at the end of every sync cycle, regardless of
(...skipping 27 matching lines...) Expand all
2485 if (!nigori.encrypted().blob().empty()) { 2498 if (!nigori.encrypted().blob().empty()) {
2486 DCHECK(!cryptographer->CanDecrypt(nigori.encrypted())); 2499 DCHECK(!cryptographer->CanDecrypt(nigori.encrypted()));
2487 cryptographer->SetPendingKeys(nigori.encrypted()); 2500 cryptographer->SetPendingKeys(nigori.encrypted());
2488 } 2501 }
2489 } 2502 }
2490 2503
2491 // If we've completed a sync cycle and the cryptographer isn't ready 2504 // If we've completed a sync cycle and the cryptographer isn't ready
2492 // yet, prompt the user for a passphrase. 2505 // yet, prompt the user for a passphrase.
2493 if (cryptographer->has_pending_keys()) { 2506 if (cryptographer->has_pending_keys()) {
2494 VLOG(1) << "OnPassPhraseRequired Sent"; 2507 VLOG(1) << "OnPassPhraseRequired Sent";
2495 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2508 NOTIFY_SYNCMANAGER_OBSERVERS(
2496 OnPassphraseRequired(sync_api::REASON_DECRYPTION)); 2509 OnPassphraseRequired(sync_api::REASON_DECRYPTION));
2497 } else if (!cryptographer->is_ready()) { 2510 } else if (!cryptographer->is_ready()) {
2498 VLOG(1) << "OnPassphraseRequired sent because cryptographer is not " 2511 VLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
2499 << "ready"; 2512 << "ready";
2500 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2513 NOTIFY_SYNCMANAGER_OBSERVERS(
2501 OnPassphraseRequired(sync_api::REASON_ENCRYPTION)); 2514 OnPassphraseRequired(sync_api::REASON_ENCRYPTION));
2502 } 2515 }
2503 // If everything is in order(we have the passphrase) then there is no 2516 // If everything is in order(we have the passphrase) then there is no
2504 // need to inform the listeners. They will just wait for sync 2517 // need to inform the listeners. They will just wait for sync
2505 // completion event and if no errors have been raised it means 2518 // completion event and if no errors have been raised it means
2506 // encryption was succesful. 2519 // encryption was succesful.
2507 } 2520 }
2508 } 2521 }
2509 2522
2510 if (!initialized()) { 2523 if (!initialized()) {
2511 VLOG(0) << "OnSyncCycleCompleted not sent because sync api is not " 2524 VLOG(0) << "OnSyncCycleCompleted not sent because sync api is not "
2512 << "initialized"; 2525 << "initialized";
2513 return; 2526 return;
2514 } 2527 }
2515 2528
2516 if (!event.snapshot->has_more_to_sync) { 2529 if (!event.snapshot->has_more_to_sync) {
2517 VLOG(1) << "OnSyncCycleCompleted sent"; 2530 VLOG(1) << "OnSyncCycleCompleted sent";
2518 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2531 NOTIFY_SYNCMANAGER_OBSERVERS(OnSyncCycleCompleted(event.snapshot));
2519 OnSyncCycleCompleted(event.snapshot));
2520 } 2532 }
2521 2533
2522 // This is here for tests, which are still using p2p notifications. 2534 // This is here for tests, which are still using p2p notifications.
2523 // SendNotification does not do anything if we are using server based 2535 // SendNotification does not do anything if we are using server based
2524 // notifications. 2536 // notifications.
2525 // TODO(chron): Consider changing this back to track has_more_to_sync 2537 // TODO(chron): Consider changing this back to track has_more_to_sync
2526 // only notify peers if a successful commit has occurred. 2538 // only notify peers if a successful commit has occurred.
2527 bool is_notifiable_commit = 2539 bool is_notifiable_commit =
2528 (event.snapshot->syncer_status.num_successful_commits > 0); 2540 (event.snapshot->syncer_status.num_successful_commits > 0);
2529 if (is_notifiable_commit) { 2541 if (is_notifiable_commit) {
2530 allstatus_.IncrementNotifiableCommits(); 2542 allstatus_.IncrementNotifiableCommits();
2531 core_message_loop_->PostTask( 2543 core_message_loop_->PostTask(
2532 FROM_HERE, 2544 FROM_HERE,
2533 NewRunnableMethod( 2545 NewRunnableMethod(
2534 this, 2546 this,
2535 &SyncManager::SyncInternal::SendNotification)); 2547 &SyncManager::SyncInternal::SendNotification));
2536 } 2548 }
2537 } 2549 }
2538 2550
2539 if (event.what_happened == SyncEngineEvent::STOP_SYNCING_PERMANENTLY) { 2551 if (event.what_happened == SyncEngineEvent::STOP_SYNCING_PERMANENTLY) {
2540 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2552 NOTIFY_SYNCMANAGER_OBSERVERS(OnStopSyncingPermanently());
2541 OnStopSyncingPermanently());
2542 return; 2553 return;
2543 } 2554 }
2544 2555
2545 if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_SUCCEEDED) { 2556 if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_SUCCEEDED) {
2546 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2557 NOTIFY_SYNCMANAGER_OBSERVERS(OnClearServerDataSucceeded());
2547 OnClearServerDataSucceeded());
2548 return; 2558 return;
2549 } 2559 }
2550 2560
2551 if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_FAILED) { 2561 if (event.what_happened == SyncEngineEvent::CLEAR_SERVER_DATA_FAILED) {
2552 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2562 NOTIFY_SYNCMANAGER_OBSERVERS(OnClearServerDataFailed());
2553 OnClearServerDataFailed());
2554 return; 2563 return;
2555 } 2564 }
2556 2565
2557 if (event.what_happened == SyncEngineEvent::UPDATED_TOKEN) { 2566 if (event.what_happened == SyncEngineEvent::UPDATED_TOKEN) {
2558 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2567 NOTIFY_SYNCMANAGER_OBSERVERS(OnUpdatedToken(event.updated_token));
2559 OnUpdatedToken(event.updated_token));
2560 return; 2568 return;
2561 } 2569 }
2562 } 2570 }
2563 2571
2564 void SyncManager::SyncInternal::SetParentJsEventRouter( 2572 void SyncManager::SyncInternal::SetParentJsEventRouter(
2565 browser_sync::JsEventRouter* router) { 2573 browser_sync::JsEventRouter* router) {
2566 DCHECK(router); 2574 DCHECK(router);
2567 parent_router_ = router; 2575 parent_router_ = router;
2568 2576
2569 // We might be called before OpenDirectory() or after shutdown. 2577 // We might be called before OpenDirectory() or after shutdown.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 } 2861 }
2854 if (VLOG_IS_ON(1)) { 2862 if (VLOG_IS_ON(1)) {
2855 std::string encoded_state; 2863 std::string encoded_state;
2856 base::Base64Encode(state, &encoded_state); 2864 base::Base64Encode(state, &encoded_state);
2857 VLOG(1) << "Writing notification state: " << encoded_state; 2865 VLOG(1) << "Writing notification state: " << encoded_state;
2858 } 2866 }
2859 lookup->SetNotificationState(state); 2867 lookup->SetNotificationState(state);
2860 lookup->SaveChanges(); 2868 lookup->SaveChanges();
2861 } 2869 }
2862 2870
2871 bool SyncManager::SyncInternal::HaveObservers() {
2872 base::AutoLock lock(observers_lock_);
2873 return observers_.size() > 0;
2874 }
2875
2863 void SyncManager::SyncInternal::AddObserver( 2876 void SyncManager::SyncInternal::AddObserver(
2864 SyncManager::Observer* observer) { 2877 SyncManager::Observer* observer) {
2878 base::AutoLock lock(observers_lock_);
2865 observers_.AddObserver(observer); 2879 observers_.AddObserver(observer);
2866 } 2880 }
2867 2881
2868 void SyncManager::SyncInternal::RemoveObserver( 2882 void SyncManager::SyncInternal::RemoveObserver(
2869 SyncManager::Observer* observer) { 2883 SyncManager::Observer* observer) {
2884 base::AutoLock lock(observers_lock_);
2870 observers_.RemoveObserver(observer); 2885 observers_.RemoveObserver(observer);
2871 } 2886 }
2872 2887
2873 SyncManager::Status::Summary SyncManager::GetStatusSummary() const { 2888 SyncManager::Status::Summary SyncManager::GetStatusSummary() const {
2874 return data_->GetStatus().summary; 2889 return data_->GetStatus().summary;
2875 } 2890 }
2876 2891
2877 SyncManager::Status SyncManager::GetDetailedStatus() const { 2892 SyncManager::Status SyncManager::GetDetailedStatus() const {
2878 return data_->GetStatus(); 2893 return data_->GetStatus();
2879 } 2894 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2950 void SyncManager::TriggerOnIncomingNotificationForTest( 2965 void SyncManager::TriggerOnIncomingNotificationForTest(
2951 const syncable::ModelTypeBitSet& model_types) { 2966 const syncable::ModelTypeBitSet& model_types) {
2952 syncable::ModelTypePayloadMap model_types_with_payloads = 2967 syncable::ModelTypePayloadMap model_types_with_payloads =
2953 syncable::ModelTypePayloadMapFromBitSet(model_types, 2968 syncable::ModelTypePayloadMapFromBitSet(model_types,
2954 std::string()); 2969 std::string());
2955 2970
2956 data_->OnIncomingNotification(model_types_with_payloads); 2971 data_->OnIncomingNotification(model_types_with_payloads);
2957 } 2972 }
2958 2973
2959 } // namespace sync_api 2974 } // namespace sync_api
OLDNEW
« no previous file with comments | « no previous file | tools/valgrind/tsan/suppressions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698