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

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

Issue 3026029: Fix EntryKernel leak if sync database load fails (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Fix legit leak in PurgeEntriesWithTypeIn Created 10 years, 4 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #if defined(OS_POSIX) 10 #if defined(OS_POSIX)
(...skipping 14 matching lines...) Expand all
25 #include <limits> 25 #include <limits>
26 #include <set> 26 #include <set>
27 #include <string> 27 #include <string>
28 28
29 #include "base/hash_tables.h" 29 #include "base/hash_tables.h"
30 #include "base/file_util.h" 30 #include "base/file_util.h"
31 #include "base/logging.h" 31 #include "base/logging.h"
32 #include "base/perftimer.h" 32 #include "base/perftimer.h"
33 #include "base/scoped_ptr.h" 33 #include "base/scoped_ptr.h"
34 #include "base/string_util.h" 34 #include "base/string_util.h"
35 #include "base/stl_util-inl.h"
35 #include "base/time.h" 36 #include "base/time.h"
36 #include "chrome/browser/sync/engine/syncer.h" 37 #include "chrome/browser/sync/engine/syncer.h"
37 #include "chrome/browser/sync/engine/syncer_util.h" 38 #include "chrome/browser/sync/engine/syncer_util.h"
38 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" 39 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
39 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 40 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
40 #include "chrome/browser/sync/protocol/password_specifics.pb.h" 41 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
41 #include "chrome/browser/sync/protocol/preference_specifics.pb.h" 42 #include "chrome/browser/sync/protocol/preference_specifics.pb.h"
42 #include "chrome/browser/sync/protocol/service_constants.h" 43 #include "chrome/browser/sync/protocol/service_constants.h"
43 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" 44 #include "chrome/browser/sync/protocol/theme_specifics.pb.h"
44 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" 45 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 unsynced_metahandles(new MetahandleSet), 177 unsynced_metahandles(new MetahandleSet),
177 dirty_metahandles(new MetahandleSet), 178 dirty_metahandles(new MetahandleSet),
178 metahandles_to_purge(new MetahandleSet), 179 metahandles_to_purge(new MetahandleSet),
179 channel(new Directory::Channel(syncable::DIRECTORY_DESTROYED)), 180 channel(new Directory::Channel(syncable::DIRECTORY_DESTROYED)),
180 info_status(Directory::KERNEL_SHARE_INFO_VALID), 181 info_status(Directory::KERNEL_SHARE_INFO_VALID),
181 persisted_info(info.kernel_info), 182 persisted_info(info.kernel_info),
182 cache_guid(info.cache_guid), 183 cache_guid(info.cache_guid),
183 next_metahandle(info.max_metahandle + 1) { 184 next_metahandle(info.max_metahandle + 1) {
184 } 185 }
185 186
186 inline void DeleteEntry(EntryKernel* kernel) {
187 delete kernel;
188 }
189
190 void Directory::Kernel::AddRef() { 187 void Directory::Kernel::AddRef() {
191 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1); 188 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1);
192 } 189 }
193 190
194 void Directory::Kernel::Release() { 191 void Directory::Kernel::Release() {
195 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1)) 192 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1))
196 delete this; 193 delete this;
197 } 194 }
198 195
199 Directory::Kernel::~Kernel() { 196 Directory::Kernel::~Kernel() {
200 CHECK(0 == refcount); 197 CHECK(0 == refcount);
201 delete channel; 198 delete channel;
202 changes_channel.Notify(kShutdownChangesEvent); 199 changes_channel.Notify(kShutdownChangesEvent);
203 delete unsynced_metahandles; 200 delete unsynced_metahandles;
204 delete unapplied_update_metahandles; 201 delete unapplied_update_metahandles;
205 delete dirty_metahandles; 202 delete dirty_metahandles;
206 delete metahandles_to_purge; 203 delete metahandles_to_purge;
207 delete parent_id_child_index; 204 delete parent_id_child_index;
208 delete client_tag_index; 205 delete client_tag_index;
209 delete ids_index; 206 delete ids_index;
210 for_each(metahandles_index->begin(), metahandles_index->end(), DeleteEntry); 207 STLDeleteElements(metahandles_index);
211 delete metahandles_index; 208 delete metahandles_index;
212 } 209 }
213 210
214 Directory::Directory() : kernel_(NULL), store_(NULL) { 211 Directory::Directory() : kernel_(NULL), store_(NULL) {
215 } 212 }
216 213
217 Directory::~Directory() { 214 Directory::~Directory() {
218 Close(); 215 Close();
219 } 216 }
220 217
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 EntryKernel* Directory::GetEntryByHandle(const int64 metahandle) { 329 EntryKernel* Directory::GetEntryByHandle(const int64 metahandle) {
333 ScopedKernelLock lock(this); 330 ScopedKernelLock lock(this);
334 return GetEntryByHandle(metahandle, &lock); 331 return GetEntryByHandle(metahandle, &lock);
335 } 332 }
336 333
337 EntryKernel* Directory::GetEntryByHandle(const int64 metahandle, 334 EntryKernel* Directory::GetEntryByHandle(const int64 metahandle,
338 ScopedKernelLock* lock) { 335 ScopedKernelLock* lock) {
339 // Look up in memory 336 // Look up in memory
340 kernel_->needle.put(META_HANDLE, metahandle); 337 kernel_->needle.put(META_HANDLE, metahandle);
341 MetahandlesIndex::iterator found = 338 MetahandlesIndex::iterator found =
342 kernel_->metahandles_index->find(&kernel_->needle); 339 kernel_->metahandles_index->find(&kernel_->needle);
343 if (found != kernel_->metahandles_index->end()) { 340 if (found != kernel_->metahandles_index->end()) {
344 // Found it in memory. Easy. 341 // Found it in memory. Easy.
345 return *found; 342 return *found;
346 } 343 }
347 return NULL; 344 return NULL;
348 } 345 }
349 346
350 // An interface to specify the details of which children 347 // An interface to specify the details of which children
351 // GetChildHandles() is looking for. 348 // GetChildHandles() is looking for.
352 // TODO(chron): Clean this up into one function to get child handles 349 // TODO(chron): Clean this up into one function to get child handles
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 ModelType local_type = GetModelTypeFromSpecifics(local_specifics); 620 ModelType local_type = GetModelTypeFromSpecifics(local_specifics);
624 ModelType server_type = GetModelTypeFromSpecifics(server_specifics); 621 ModelType server_type = GetModelTypeFromSpecifics(server_specifics);
625 622
626 // Note the dance around incrementing |it|, since we sometimes erase(). 623 // Note the dance around incrementing |it|, since we sometimes erase().
627 if (types.count(local_type) > 0 || types.count(server_type) > 0) { 624 if (types.count(local_type) > 0 || types.count(server_type) > 0) {
628 UnlinkEntryFromOrder(*it, NULL, &lock); 625 UnlinkEntryFromOrder(*it, NULL, &lock);
629 int64 handle = (*it)->ref(META_HANDLE); 626 int64 handle = (*it)->ref(META_HANDLE);
630 kernel_->metahandles_to_purge->insert(handle); 627 kernel_->metahandles_to_purge->insert(handle);
631 628
632 size_t num_erased = 0; 629 size_t num_erased = 0;
633 num_erased = kernel_->ids_index->erase(*it); 630 EntryKernel* entry = *it;
631 num_erased = kernel_->ids_index->erase(entry);
634 DCHECK_EQ(1u, num_erased); 632 DCHECK_EQ(1u, num_erased);
635 num_erased = kernel_->client_tag_index->erase(*it); 633 num_erased = kernel_->client_tag_index->erase(entry);
636 DCHECK_EQ((*it)->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); 634 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased);
637 num_erased = kernel_->unsynced_metahandles->erase(handle); 635 num_erased = kernel_->unsynced_metahandles->erase(handle);
638 DCHECK_EQ((*it)->ref(IS_UNSYNCED), num_erased > 0); 636 DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0);
639 num_erased = kernel_->unapplied_update_metahandles->erase(handle); 637 num_erased = kernel_->unapplied_update_metahandles->erase(handle);
640 DCHECK_EQ((*it)->ref(IS_UNAPPLIED_UPDATE), num_erased > 0); 638 DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0);
641 num_erased = kernel_->parent_id_child_index->erase(*it); 639 num_erased = kernel_->parent_id_child_index->erase(entry);
642 DCHECK_EQ((*it)->ref(IS_DEL), !num_erased); 640 DCHECK_EQ(entry->ref(IS_DEL), !num_erased);
643 kernel_->metahandles_index->erase(it++); 641 kernel_->metahandles_index->erase(it++);
642 delete entry;
644 } else { 643 } else {
645 ++it; 644 ++it;
646 } 645 }
647 } 646 }
648 647
649 // Ensure meta tracking for these data types reflects the deleted state. 648 // Ensure meta tracking for these data types reflects the deleted state.
650 for (std::set<ModelType>::const_iterator it = types.begin(); 649 for (std::set<ModelType>::const_iterator it = types.begin();
651 it != types.end(); ++it) { 650 it != types.end(); ++it) {
652 set_initial_sync_ended_for_type_unsafe(*it, false); 651 set_initial_sync_ended_for_type_unsafe(*it, false);
653 set_last_download_timestamp_unsafe(*it, 0); 652 set_last_download_timestamp_unsafe(*it, 0);
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 return s << std::dec; 1578 return s << std::dec;
1580 } 1579 }
1581 1580
1582 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) { 1581 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) {
1583 if (blob.empty()) 1582 if (blob.empty())
1584 return dump; 1583 return dump;
1585 string buffer(HexEncode(&blob[0], blob.size())); 1584 string buffer(HexEncode(&blob[0], blob.size()));
1586 dump.out_->sputn(buffer.c_str(), buffer.size()); 1585 dump.out_->sputn(buffer.c_str(), buffer.size());
1587 return dump; 1586 return dump;
1588 } 1587 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698