OLD | NEW |
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/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <functional> | 9 #include <functional> |
10 #include <iomanip> | 10 #include <iomanip> |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "chrome/browser/sync/syncable/model_type.h" | 34 #include "chrome/browser/sync/syncable/model_type.h" |
35 #include "chrome/browser/sync/syncable/syncable_changes_version.h" | 35 #include "chrome/browser/sync/syncable/syncable_changes_version.h" |
36 #include "chrome/browser/sync/syncable/syncable_columns.h" | 36 #include "chrome/browser/sync/syncable/syncable_columns.h" |
37 #include "chrome/browser/sync/syncable/syncable_enum_conversions.h" | 37 #include "chrome/browser/sync/syncable/syncable_enum_conversions.h" |
38 #include "chrome/browser/sync/syncable/syncable-inl.h" | 38 #include "chrome/browser/sync/syncable/syncable-inl.h" |
39 #include "chrome/browser/sync/syncable/transaction_observer.h" | 39 #include "chrome/browser/sync/syncable/transaction_observer.h" |
40 #include "chrome/browser/sync/util/logging.h" | 40 #include "chrome/browser/sync/util/logging.h" |
41 #include "net/base/escape.h" | 41 #include "net/base/escape.h" |
42 | 42 |
43 namespace { | 43 namespace { |
| 44 |
44 enum InvariantCheckLevel { | 45 enum InvariantCheckLevel { |
45 OFF = 0, | 46 OFF = 0, |
46 VERIFY_IN_MEMORY = 1, | 47 VERIFY_IN_MEMORY = 1, |
47 FULL_DB_VERIFICATION = 2 | 48 FULL_DB_VERIFICATION = 2 |
48 }; | 49 }; |
49 | 50 |
50 static const InvariantCheckLevel kInvariantCheckLevel = VERIFY_IN_MEMORY; | 51 static const InvariantCheckLevel kInvariantCheckLevel = VERIFY_IN_MEMORY; |
51 | 52 |
52 // Max number of milliseconds to spend checking syncable entry invariants | 53 // Max number of milliseconds to spend checking syncable entry invariants |
53 static const int kInvariantCheckMaxMs = 50; | 54 static const int kInvariantCheckMaxMs = 50; |
54 } // namespace | 55 |
| 56 } // namespace. |
55 | 57 |
56 using std::string; | 58 using std::string; |
57 | 59 |
58 namespace syncable { | 60 namespace syncable { |
59 | 61 |
60 #define ENUM_CASE(x) case x: return #x; break | 62 #define ENUM_CASE(x) case x: return #x; break |
61 | 63 |
62 std::string WriterTagToString(WriterTag writer_tag) { | 64 std::string WriterTagToString(WriterTag writer_tag) { |
63 switch (writer_tag) { | 65 switch (writer_tag) { |
64 ENUM_CASE(INVALID); | 66 ENUM_CASE(INVALID); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 delete unapplied_update_metahandles; | 420 delete unapplied_update_metahandles; |
419 delete dirty_metahandles; | 421 delete dirty_metahandles; |
420 delete metahandles_to_purge; | 422 delete metahandles_to_purge; |
421 delete parent_id_child_index; | 423 delete parent_id_child_index; |
422 delete client_tag_index; | 424 delete client_tag_index; |
423 delete ids_index; | 425 delete ids_index; |
424 STLDeleteElements(metahandles_index); | 426 STLDeleteElements(metahandles_index); |
425 delete metahandles_index; | 427 delete metahandles_index; |
426 } | 428 } |
427 | 429 |
428 Directory::Directory() : kernel_(NULL), store_(NULL) { | 430 Directory::Directory() : kernel_(NULL), store_(NULL), |
| 431 unrecoverable_error_(false) { |
429 } | 432 } |
430 | 433 |
431 Directory::~Directory() { | 434 Directory::~Directory() { |
432 Close(); | 435 Close(); |
433 } | 436 } |
434 | 437 |
435 DirOpenResult Directory::Open(const FilePath& file_path, const string& name, | 438 DirOpenResult Directory::Open(const FilePath& file_path, const string& name, |
436 DirectoryChangeDelegate* delegate) { | 439 DirectoryChangeDelegate* delegate) { |
437 const DirOpenResult result = OpenImpl(file_path, name, delegate); | 440 const DirOpenResult result = OpenImpl(file_path, name, delegate); |
438 if (OPENED != result) | 441 if (OPENED != result) |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // greater magnitude than could possibly be reached before the next save | 692 // greater magnitude than could possibly be reached before the next save |
690 // changes. In other words, it's effectively impossible for the user to | 693 // changes. In other words, it's effectively impossible for the user to |
691 // generate 65536 new bookmarks in 3 seconds. | 694 // generate 65536 new bookmarks in 3 seconds. |
692 snapshot->kernel_info.next_id -= 65536; | 695 snapshot->kernel_info.next_id -= 65536; |
693 snapshot->kernel_info_status = kernel_->info_status; | 696 snapshot->kernel_info_status = kernel_->info_status; |
694 // This one we reset on failure. | 697 // This one we reset on failure. |
695 kernel_->info_status = KERNEL_SHARE_INFO_VALID; | 698 kernel_->info_status = KERNEL_SHARE_INFO_VALID; |
696 } | 699 } |
697 | 700 |
698 bool Directory::SaveChanges() { | 701 bool Directory::SaveChanges() { |
| 702 if (unrecoverable_error_) |
| 703 return true; |
699 bool success = false; | 704 bool success = false; |
700 DCHECK(store_); | 705 DCHECK(store_); |
701 | 706 |
702 base::AutoLock scoped_lock(kernel_->save_changes_mutex); | 707 base::AutoLock scoped_lock(kernel_->save_changes_mutex); |
703 | 708 |
704 // Snapshot and save. | 709 // Snapshot and save. |
705 SaveChangesSnapshot snapshot; | 710 SaveChangesSnapshot snapshot; |
706 TakeSnapshotForSaveChanges(&snapshot); | 711 TakeSnapshotForSaveChanges(&snapshot); |
707 success = store_->SaveChanges(snapshot); | 712 success = store_->SaveChanges(snapshot); |
708 | 713 |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 } | 1115 } |
1111 | 1116 |
1112 void Directory::AddTransactionObserver(TransactionObserver* observer) { | 1117 void Directory::AddTransactionObserver(TransactionObserver* observer) { |
1113 kernel_->observers->AddObserver(observer); | 1118 kernel_->observers->AddObserver(observer); |
1114 } | 1119 } |
1115 | 1120 |
1116 void Directory::RemoveTransactionObserver(TransactionObserver* observer) { | 1121 void Directory::RemoveTransactionObserver(TransactionObserver* observer) { |
1117 kernel_->observers->RemoveObserver(observer); | 1122 kernel_->observers->RemoveObserver(observer); |
1118 } | 1123 } |
1119 | 1124 |
| 1125 void Directory::set_unrecoverable_error() { |
| 1126 unrecoverable_error_ = true; |
| 1127 } |
| 1128 |
| 1129 bool Directory::unrecoverable_error() const { |
| 1130 return unrecoverable_error_; |
| 1131 } |
| 1132 |
1120 /////////////////////////////////////////////////////////////////////////////// | 1133 /////////////////////////////////////////////////////////////////////////////// |
1121 // ScopedKernelLock | 1134 // ScopedKernelLock |
1122 | 1135 |
1123 ScopedKernelLock::ScopedKernelLock(const Directory* dir) | 1136 ScopedKernelLock::ScopedKernelLock(const Directory* dir) |
1124 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { | 1137 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { |
1125 } | 1138 } |
1126 | 1139 |
1127 /////////////////////////////////////////////////////////////////////////// | 1140 /////////////////////////////////////////////////////////////////////////// |
1128 // Transactions | 1141 // Transactions |
1129 | 1142 |
(...skipping 20 matching lines...) Expand all Loading... |
1150 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, | 1163 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, |
1151 const char* name, | 1164 const char* name, |
1152 WriterTag writer, | 1165 WriterTag writer, |
1153 Directory* directory) | 1166 Directory* directory) |
1154 : from_here_(from_here), name_(name), writer_(writer), | 1167 : from_here_(from_here), name_(name), writer_(writer), |
1155 directory_(directory), dirkernel_(directory->kernel_) { | 1168 directory_(directory), dirkernel_(directory->kernel_) { |
1156 dirkernel_->observers->Notify( | 1169 dirkernel_->observers->Notify( |
1157 &TransactionObserver::OnTransactionStart, from_here_, writer_); | 1170 &TransactionObserver::OnTransactionStart, from_here_, writer_); |
1158 } | 1171 } |
1159 | 1172 |
| 1173 void BaseTransaction::set_unrecoverable_error() { |
| 1174 directory_->set_unrecoverable_error(); |
| 1175 } |
| 1176 |
1160 BaseTransaction::~BaseTransaction() { | 1177 BaseTransaction::~BaseTransaction() { |
1161 dirkernel_->observers->Notify( | 1178 dirkernel_->observers->Notify( |
1162 &TransactionObserver::OnTransactionEnd, from_here_, writer_); | 1179 &TransactionObserver::OnTransactionEnd, from_here_, writer_); |
1163 } | 1180 } |
1164 | 1181 |
1165 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, | 1182 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, |
1166 Directory* directory) | 1183 Directory* directory) |
1167 : BaseTransaction(location, "Read", INVALID, directory) { | 1184 : BaseTransaction(location, "Read", INVALID, directory) { |
1168 Lock(); | 1185 Lock(); |
1169 } | 1186 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 | 1292 |
1276 void WriteTransaction::NotifyTransactionComplete( | 1293 void WriteTransaction::NotifyTransactionComplete( |
1277 ModelTypeBitSet models_with_changes) { | 1294 ModelTypeBitSet models_with_changes) { |
1278 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( | 1295 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( |
1279 models_with_changes); | 1296 models_with_changes); |
1280 } | 1297 } |
1281 | 1298 |
1282 WriteTransaction::~WriteTransaction() { | 1299 WriteTransaction::~WriteTransaction() { |
1283 const ImmutableEntryKernelMutationMap& mutations = RecordMutations(); | 1300 const ImmutableEntryKernelMutationMap& mutations = RecordMutations(); |
1284 | 1301 |
| 1302 if (directory_->unrecoverable_error()) |
| 1303 return; |
1285 if (OFF != kInvariantCheckLevel) { | 1304 if (OFF != kInvariantCheckLevel) { |
1286 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); | 1305 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); |
1287 if (full_scan) | 1306 if (full_scan) |
1288 directory()->CheckTreeInvariants(this, full_scan); | 1307 directory()->CheckTreeInvariants(this, full_scan); |
1289 else | 1308 else |
1290 directory()->CheckTreeInvariants(this, mutations.Get()); | 1309 directory()->CheckTreeInvariants(this, mutations.Get()); |
1291 } | 1310 } |
1292 | 1311 |
1293 UnlockAndNotify(mutations); | 1312 UnlockAndNotify(mutations); |
1294 } | 1313 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 ScopedIndexUpdater<ParentIdAndHandleIndexer> updater(lock, kernel_, | 1497 ScopedIndexUpdater<ParentIdAndHandleIndexer> updater(lock, kernel_, |
1479 dir()->kernel_->parent_id_child_index); | 1498 dir()->kernel_->parent_id_child_index); |
1480 | 1499 |
1481 kernel_->put(IS_DEL, is_del); | 1500 kernel_->put(IS_DEL, is_del); |
1482 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); | 1501 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
1483 } | 1502 } |
1484 | 1503 |
1485 if (!is_del) | 1504 if (!is_del) |
1486 // Restores position to the 0th index. | 1505 // Restores position to the 0th index. |
1487 if (!PutPredecessor(Id())) { | 1506 if (!PutPredecessor(Id())) { |
1488 // TODO(lipalani) : Propagate the error to caller. crbug.com/100444. | 1507 return false; |
1489 NOTREACHED(); | |
1490 } | 1508 } |
1491 | 1509 |
1492 return true; | 1510 return true; |
1493 } | 1511 } |
1494 | 1512 |
1495 bool MutableEntry::Put(Int64Field field, const int64& value) { | 1513 bool MutableEntry::Put(Int64Field field, const int64& value) { |
1496 DCHECK(kernel_); | 1514 DCHECK(kernel_); |
1497 if (kernel_->ref(field) != value) { | 1515 if (kernel_->ref(field) != value) { |
1498 ScopedKernelLock lock(dir()); | 1516 ScopedKernelLock lock(dir()); |
1499 if (SERVER_POSITION_IN_PARENT == field) { | 1517 if (SERVER_POSITION_IN_PARENT == field) { |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1978 CHECK(result); | 1996 CHECK(result); |
1979 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id), | 1997 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id), |
1980 end = GetParentChildIndexUpperBound(lock, parent_id); | 1998 end = GetParentChildIndexUpperBound(lock, parent_id); |
1981 i != end; ++i) { | 1999 i != end; ++i) { |
1982 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); | 2000 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); |
1983 result->push_back((*i)->ref(META_HANDLE)); | 2001 result->push_back((*i)->ref(META_HANDLE)); |
1984 } | 2002 } |
1985 } | 2003 } |
1986 | 2004 |
1987 } // namespace syncable | 2005 } // namespace syncable |
OLD | NEW |