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

Side by Side Diff: chrome/browser/sync/syncable/syncable.h

Issue 7190001: [Sync] Split DirectoryChangeListener for thread-safety (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix copyright 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
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 #ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ 5 #ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
6 #define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ 6 #define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
7 #pragma once 7 #pragma once
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <bitset> 10 #include <bitset>
11 #include <iosfwd> 11 #include <iosfwd>
12 #include <limits> 12 #include <limits>
13 #include <set> 13 #include <set>
14 #include <string> 14 #include <string>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/atomicops.h" 17 #include "base/atomicops.h"
18 #include "base/basictypes.h" 18 #include "base/basictypes.h"
19 #include "base/file_path.h" 19 #include "base/file_path.h"
20 #include "base/gtest_prod_util.h" 20 #include "base/gtest_prod_util.h"
21 #include "base/observer_list.h" 21 #include "base/memory/ref_counted.h"
22 #include "base/observer_list_threadsafe.h"
22 #include "base/synchronization/lock.h" 23 #include "base/synchronization/lock.h"
23 #include "base/time.h" 24 #include "base/time.h"
25 #include "base/tracked.h"
24 #include "chrome/browser/sync/protocol/sync.pb.h" 26 #include "chrome/browser/sync/protocol/sync.pb.h"
25 #include "chrome/browser/sync/syncable/autofill_migration.h" 27 #include "chrome/browser/sync/syncable/autofill_migration.h"
26 #include "chrome/browser/sync/syncable/blob.h" 28 #include "chrome/browser/sync/syncable/blob.h"
27 #include "chrome/browser/sync/syncable/dir_open_result.h" 29 #include "chrome/browser/sync/syncable/dir_open_result.h"
28 #include "chrome/browser/sync/syncable/directory_event.h" 30 #include "chrome/browser/sync/syncable/directory_event.h"
29 #include "chrome/browser/sync/syncable/syncable_id.h" 31 #include "chrome/browser/sync/syncable/syncable_id.h"
30 #include "chrome/browser/sync/syncable/model_type.h" 32 #include "chrome/browser/sync/syncable/model_type.h"
31 #include "chrome/browser/sync/util/dbgq.h" 33 #include "chrome/browser/sync/util/dbgq.h"
32 #include "chrome/common/deprecated/event_sys.h" 34 #include "chrome/common/deprecated/event_sys.h"
33 35
34 class DictionaryValue; 36 class DictionaryValue;
35 struct PurgeInfo; 37 struct PurgeInfo;
36 38
37 namespace sync_api { 39 namespace sync_api {
38 class ReadTransaction; 40 class ReadTransaction;
39 class WriteNode; 41 class WriteNode;
40 class ReadNode; 42 class ReadNode;
41 } 43 } // sync_api
42 44
43 namespace syncable { 45 namespace syncable {
44 class DirectoryChangeListener; 46 class DirectoryChangeDelegate;
47 class TransactionObserver;
45 class Entry; 48 class Entry;
46 49
47 std::ostream& operator<<(std::ostream& s, const Entry& e); 50 std::ostream& operator<<(std::ostream& s, const Entry& e);
48 51
49 class DirectoryBackingStore; 52 class DirectoryBackingStore;
50 53
51 static const int64 kInvalidMetaHandle = 0; 54 static const int64 kInvalidMetaHandle = 0;
52 55
53 // Update syncable_enum_conversions{.h,.cc,_unittest.cc} if you change 56 // Update syncable_enum_conversions{.h,.cc,_unittest.cc} if you change
54 // any fields in this file. 57 // any fields in this file.
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 750
748 KernelShareInfoStatus kernel_info_status; 751 KernelShareInfoStatus kernel_info_status;
749 PersistedKernelInfo kernel_info; 752 PersistedKernelInfo kernel_info;
750 OriginalEntries dirty_metas; 753 OriginalEntries dirty_metas;
751 MetahandleSet metahandles_to_purge; 754 MetahandleSet metahandles_to_purge;
752 }; 755 };
753 756
754 Directory(); 757 Directory();
755 virtual ~Directory(); 758 virtual ~Directory();
756 759
757 DirOpenResult Open(const FilePath& file_path, const std::string& name); 760 // Does not take ownership of |delegate|, which must not be NULL.
761 // Starts sending events to |delegate| if the returned result is
762 // OPENED. Note that events to |delegate| may be sent from *any*
763 // thread.
764 DirOpenResult Open(const FilePath& file_path, const std::string& name,
765 DirectoryChangeDelegate* delegate);
758 766
767 // Stops sending events to the delegate.
759 void Close(); 768 void Close();
760 769
761 int64 NextMetahandle(); 770 int64 NextMetahandle();
762 // Always returns a negative id. Positive client ids are generated 771 // Always returns a negative id. Positive client ids are generated
763 // by the server only. 772 // by the server only.
764 Id NextId(); 773 Id NextId();
765 774
766 const FilePath& file_path() const { return kernel_->db_path; } 775 const FilePath& file_path() const { return kernel_->db_path; }
767 bool good() const { return NULL != store_; } 776 bool good() const { return NULL != store_; }
768 777
(...skipping 29 matching lines...) Expand all
798 // later. 807 // later.
799 std::string store_birthday() const; 808 std::string store_birthday() const;
800 void set_store_birthday(const std::string& store_birthday); 809 void set_store_birthday(const std::string& store_birthday);
801 810
802 std::string GetAndClearNotificationState(); 811 std::string GetAndClearNotificationState();
803 void SetNotificationState(const std::string& notification_state); 812 void SetNotificationState(const std::string& notification_state);
804 813
805 // Unique to each account / client pair. 814 // Unique to each account / client pair.
806 std::string cache_guid() const; 815 std::string cache_guid() const;
807 816
808 void AddChangeListener(DirectoryChangeListener* listener); 817 // These are backed by a thread-safe observer list, and so can be
809 void RemoveChangeListener(DirectoryChangeListener* listener); 818 // called on any thread, and events will be sent to the observer on
819 // the same thread that it was added on.
820 void AddTransactionObserver(TransactionObserver* observer);
821 void RemoveTransactionObserver(TransactionObserver* observer);
810 822
811 protected: // for friends, mainly used by Entry constructors 823 protected: // for friends, mainly used by Entry constructors
812 virtual EntryKernel* GetEntryByHandle(int64 handle); 824 virtual EntryKernel* GetEntryByHandle(int64 handle);
813 virtual EntryKernel* GetEntryByHandle(int64 metahandle, 825 virtual EntryKernel* GetEntryByHandle(int64 metahandle,
814 ScopedKernelLock* lock); 826 ScopedKernelLock* lock);
815 virtual EntryKernel* GetEntryById(const Id& id); 827 virtual EntryKernel* GetEntryById(const Id& id);
816 EntryKernel* GetEntryByServerTag(const std::string& tag); 828 EntryKernel* GetEntryByServerTag(const std::string& tag);
817 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); 829 virtual EntryKernel* GetEntryByClientTag(const std::string& tag);
818 EntryKernel* GetRootEntry(); 830 EntryKernel* GetRootEntry();
819 bool ReindexId(EntryKernel* const entry, const Id& new_id); 831 bool ReindexId(EntryKernel* const entry, const Id& new_id);
820 void ReindexParentId(EntryKernel* const entry, const Id& new_parent_id); 832 void ReindexParentId(EntryKernel* const entry, const Id& new_parent_id);
821 void ClearDirtyMetahandles(); 833 void ClearDirtyMetahandles();
822 834
823 // These don't do semantic checking. 835 // These don't do semantic checking.
824 // The semantic checking is implemented higher up. 836 // The semantic checking is implemented higher up.
825 void UnlinkEntryFromOrder(EntryKernel* entry, 837 void UnlinkEntryFromOrder(EntryKernel* entry,
826 WriteTransaction* trans, 838 WriteTransaction* trans,
827 ScopedKernelLock* lock); 839 ScopedKernelLock* lock);
828 840
829 // Overridden by tests. 841 // Overridden by tests.
830 virtual DirectoryBackingStore* CreateBackingStore( 842 virtual DirectoryBackingStore* CreateBackingStore(
831 const std::string& dir_name, 843 const std::string& dir_name,
832 const FilePath& backing_filepath); 844 const FilePath& backing_filepath);
833 845
834 private: 846 private:
835 // These private versions expect the kernel lock to already be held 847 // These private versions expect the kernel lock to already be held
836 // before calling. 848 // before calling.
837 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock); 849 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock);
838 850
839 DirOpenResult OpenImpl(const FilePath& file_path, const std::string& name); 851 DirOpenResult OpenImpl(const FilePath& file_path, const std::string& name,
852 DirectoryChangeDelegate* delegate);
840 853
841 template <class T> void TestAndSet(T* kernel_data, const T* data_to_set); 854 template <class T> void TestAndSet(T* kernel_data, const T* data_to_set);
842 855
843 struct DirectoryEventTraits { 856 struct DirectoryEventTraits {
844 typedef DirectoryEvent EventType; 857 typedef DirectoryEvent EventType;
845 static inline bool IsChannelShutdownEvent(const DirectoryEvent& event) { 858 static inline bool IsChannelShutdownEvent(const DirectoryEvent& event) {
846 return DIRECTORY_DESTROYED == event; 859 return DIRECTORY_DESTROYED == event;
847 } 860 }
848 }; 861 };
849 public: 862 public:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 typedef Index<ParentIdAndHandleIndexer>::Set ParentIdChildIndex; 989 typedef Index<ParentIdAndHandleIndexer>::Set ParentIdChildIndex;
977 990
978 // Contains both deleted and existing entries with tags. 991 // Contains both deleted and existing entries with tags.
979 // We can't store only existing tags because the client would create 992 // We can't store only existing tags because the client would create
980 // items that had a duplicated ID in the end, resulting in a DB key 993 // items that had a duplicated ID in the end, resulting in a DB key
981 // violation. ID reassociation would fail after an attempted commit. 994 // violation. ID reassociation would fail after an attempted commit.
982 typedef Index<ClientTagIndexer>::Set ClientTagIndex; 995 typedef Index<ClientTagIndexer>::Set ClientTagIndex;
983 996
984 protected: 997 protected:
985 // Used by tests. 998 // Used by tests.
986 void init_kernel(const std::string& name); 999 void InitKernel(const std::string& name, DirectoryChangeDelegate* delegate);
987 1000
988 private: 1001 private:
989 1002
990 struct Kernel { 1003 struct Kernel {
1004 // |delegate| can be NULL.
991 Kernel(const FilePath& db_path, const std::string& name, 1005 Kernel(const FilePath& db_path, const std::string& name,
992 const KernelLoadInfo& info); 1006 const KernelLoadInfo& info, DirectoryChangeDelegate* delegate);
993 1007
994 ~Kernel(); 1008 ~Kernel();
995 1009
996 void AddRef(); // For convenience. 1010 void AddRef(); // For convenience.
997 void Release(); 1011 void Release();
998 1012
999 void AddChangeListener(DirectoryChangeListener* listener);
1000 void RemoveChangeListener(DirectoryChangeListener* listener);
1001
1002 void CopyChangeListeners(
1003 ObserverList<DirectoryChangeListener>* change_listeners);
1004
1005 FilePath const db_path; 1013 FilePath const db_path;
1006 // TODO(timsteele): audit use of the member and remove if possible 1014 // TODO(timsteele): audit use of the member and remove if possible
1007 volatile base::subtle::AtomicWord refcount; 1015 volatile base::subtle::AtomicWord refcount;
1008 1016
1009 // Implements ReadTransaction / WriteTransaction using a simple lock. 1017 // Implements ReadTransaction / WriteTransaction using a simple lock.
1010 base::Lock transaction_mutex; 1018 base::Lock transaction_mutex;
1011 1019
1012 // The name of this directory. 1020 // The name of this directory.
1013 std::string const name; 1021 std::string const name;
1014 1022
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 // time; this mutex protects that activity. 1069 // time; this mutex protects that activity.
1062 base::Lock save_changes_mutex; 1070 base::Lock save_changes_mutex;
1063 1071
1064 // The next metahandle is protected by kernel mutex. 1072 // The next metahandle is protected by kernel mutex.
1065 int64 next_metahandle; 1073 int64 next_metahandle;
1066 1074
1067 // Keep a history of recently flushed metahandles for debugging 1075 // Keep a history of recently flushed metahandles for debugging
1068 // purposes. Protected by the save_changes_mutex. 1076 // purposes. Protected by the save_changes_mutex.
1069 DebugQueue<int64, 1000> flushed_metahandles; 1077 DebugQueue<int64, 1000> flushed_metahandles;
1070 1078
1071 private: 1079 // The delegate for directory change events. Can be NULL.
1072 // The listeners for directory change events, triggered when the 1080 DirectoryChangeDelegate* const delegate;
1073 // transaction is ending (and its lock). 1081
1074 base::Lock change_listeners_lock_; 1082 // The transaction observers.
1075 ObserverList<DirectoryChangeListener> change_listeners_; 1083 scoped_refptr<ObserverListThreadSafe<TransactionObserver> > observers;
1076 }; 1084 };
1077 1085
1078 // Helper method used to do searches on |parent_id_child_index|. 1086 // Helper method used to do searches on |parent_id_child_index|.
1079 ParentIdChildIndex::iterator LocateInParentChildIndex( 1087 ParentIdChildIndex::iterator LocateInParentChildIndex(
1080 const ScopedKernelLock& lock, 1088 const ScopedKernelLock& lock,
1081 const Id& parent_id, 1089 const Id& parent_id,
1082 int64 position_in_parent, 1090 int64 position_in_parent,
1083 const Id& item_id_for_tiebreaking); 1091 const Id& item_id_for_tiebreaking);
1084 1092
1085 // Return an iterator to the beginning of the range of the children of 1093 // Return an iterator to the beginning of the range of the children of
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 // Transactions are now processed FIFO with a straight lock 1125 // Transactions are now processed FIFO with a straight lock
1118 class BaseTransaction { 1126 class BaseTransaction {
1119 friend class Entry; 1127 friend class Entry;
1120 public: 1128 public:
1121 inline Directory* directory() const { return directory_; } 1129 inline Directory* directory() const { return directory_; }
1122 inline Id root_id() const { return Id(); } 1130 inline Id root_id() const { return Id(); }
1123 1131
1124 virtual ~BaseTransaction(); 1132 virtual ~BaseTransaction();
1125 1133
1126 protected: 1134 protected:
1127 BaseTransaction(Directory* directory, const char* name, 1135 BaseTransaction(Directory* directory,
1128 const char* source_file, int line, WriterTag writer); 1136 const char* name,
1129 1137 const tracked_objects::Location& from_here,
1130 // For unit testing. Everything will be mocked out no point initializing. 1138 WriterTag writer);
1131 explicit BaseTransaction(Directory* directory);
1132 1139
1133 void UnlockAndLog(OriginalEntries* entries); 1140 void UnlockAndLog(OriginalEntries* entries);
1134 virtual bool NotifyTransactionChangingAndEnding( 1141 virtual bool NotifyTransactionChangingAndEnding(
1135 OriginalEntries* entries, 1142 OriginalEntries* entries,
1136 ModelTypeBitSet* models_with_changes); 1143 ModelTypeBitSet* models_with_changes);
1137 virtual void NotifyTransactionComplete(ModelTypeBitSet models_with_changes); 1144 virtual void NotifyTransactionComplete(ModelTypeBitSet models_with_changes);
1138 1145
1139 Directory* const directory_; 1146 Directory* const directory_;
1140 Directory::Kernel* const dirkernel_; // for brevity 1147 Directory::Kernel* const dirkernel_; // for brevity
1141 const char* const name_; 1148 const char* const name_;
1142 base::TimeTicks time_acquired_; 1149 base::TimeTicks time_acquired_;
1143 const char* const source_file_; 1150 const tracked_objects::Location from_here_;
1144 const int line_;
1145 WriterTag writer_; 1151 WriterTag writer_;
1146 1152
1147 private: 1153 private:
1148 void Lock(); 1154 void Lock();
1149 1155
1150 DISALLOW_COPY_AND_ASSIGN(BaseTransaction); 1156 DISALLOW_COPY_AND_ASSIGN(BaseTransaction);
1151 }; 1157 };
1152 1158
1153 // Locks db in constructor, unlocks in destructor. 1159 // Locks db in constructor, unlocks in destructor.
1154 class ReadTransaction : public BaseTransaction { 1160 class ReadTransaction : public BaseTransaction {
1155 public: 1161 public:
1156 ReadTransaction(Directory* directory, const char* source_file, 1162 ReadTransaction(Directory* directory,
1157 int line); 1163 const tracked_objects::Location& from_here);
1158 ReadTransaction(const ScopedDirLookup& scoped_dir, 1164 ReadTransaction(const ScopedDirLookup& scoped_dir,
1159 const char* source_file, int line); 1165 const tracked_objects::Location& from_here);
1160 1166
1161 virtual ~ReadTransaction(); 1167 virtual ~ReadTransaction();
1162 1168
1163 protected: // Don't allow creation on heap, except by sync API wrapper. 1169 protected: // Don't allow creation on heap, except by sync API wrapper.
1164 friend class sync_api::ReadTransaction; 1170 friend class sync_api::ReadTransaction;
1165 void* operator new(size_t size) { return (::operator new)(size); } 1171 void* operator new(size_t size) { return (::operator new)(size); }
1166 1172
1167 DISALLOW_COPY_AND_ASSIGN(ReadTransaction); 1173 DISALLOW_COPY_AND_ASSIGN(ReadTransaction);
1168 }; 1174 };
1169 1175
1170 // Locks db in constructor, unlocks in destructor. 1176 // Locks db in constructor, unlocks in destructor.
1171 class WriteTransaction : public BaseTransaction { 1177 class WriteTransaction : public BaseTransaction {
1172 friend class MutableEntry; 1178 friend class MutableEntry;
1173 public: 1179 public:
1174 explicit WriteTransaction(Directory* directory, WriterTag writer, 1180 WriteTransaction(Directory* directory, WriterTag writer,
1175 const char* source_file, int line); 1181 const tracked_objects::Location& from_here);
1176 explicit WriteTransaction(const ScopedDirLookup& directory, 1182 WriteTransaction(const ScopedDirLookup& directory, WriterTag writer,
1177 WriterTag writer, const char* source_file, 1183 const tracked_objects::Location& from_here);
1178 int line);
1179 virtual ~WriteTransaction(); 1184 virtual ~WriteTransaction();
1180 1185
1181 void SaveOriginal(EntryKernel* entry); 1186 void SaveOriginal(EntryKernel* entry);
1182 1187
1183 protected: 1188 protected:
1184 // Before an entry gets modified, we copy the original into a list 1189 // Before an entry gets modified, we copy the original into a list
1185 // so that we can issue change notifications when the transaction 1190 // so that we can issue change notifications when the transaction
1186 // is done. 1191 // is done.
1187 OriginalEntries* const originals_; 1192 OriginalEntries* const originals_;
1188 1193
1189 explicit WriteTransaction(Directory *directory);
1190
1191 DISALLOW_COPY_AND_ASSIGN(WriteTransaction); 1194 DISALLOW_COPY_AND_ASSIGN(WriteTransaction);
1192 }; 1195 };
1193 1196
1194 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); 1197 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid);
1195 1198
1196 int64 Now(); 1199 int64 Now();
1197 1200
1198 // This function sets only the flags needed to get this entry to sync. 1201 // This function sets only the flags needed to get this entry to sync.
1199 void MarkForSyncing(syncable::MutableEntry* e); 1202 void MarkForSyncing(syncable::MutableEntry* e);
1200 1203
1201 // This is not a reset. It just sets the numeric fields which are not 1204 // This is not a reset. It just sets the numeric fields which are not
1202 // initialized by the constructor to zero. 1205 // initialized by the constructor to zero.
1203 void ZeroFields(EntryKernel* entry, int first_field); 1206 void ZeroFields(EntryKernel* entry, int first_field);
1204 1207
1205 } // namespace syncable 1208 } // namespace syncable
1206 1209
1207 std::ostream& operator <<(std::ostream&, const syncable::Blob&); 1210 std::ostream& operator <<(std::ostream&, const syncable::Blob&);
1208 1211
1209 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ 1212 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/syncable/directory_manager.cc ('k') | chrome/browser/sync/syncable/syncable.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698