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

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

Issue 2805095: Fix deadlock by introducing a new transaction event. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 } 943 }
944 } 944 }
945 945
946 BaseTransaction::BaseTransaction(Directory* directory, const char* name, 946 BaseTransaction::BaseTransaction(Directory* directory, const char* name,
947 const char* source_file, int line, WriterTag writer) 947 const char* source_file, int line, WriterTag writer)
948 : directory_(directory), dirkernel_(directory->kernel_), name_(name), 948 : directory_(directory), dirkernel_(directory->kernel_), name_(name),
949 source_file_(source_file), line_(line), writer_(writer) { 949 source_file_(source_file), line_(line), writer_(writer) {
950 Lock(); 950 Lock();
951 } 951 }
952 952
953 BaseTransaction::~BaseTransaction() {}
954
953 void BaseTransaction::UnlockAndLog(OriginalEntries* originals_arg) { 955 void BaseTransaction::UnlockAndLog(OriginalEntries* originals_arg) {
954 dirkernel_->transaction_mutex.AssertAcquired(); 956 dirkernel_->transaction_mutex.AssertAcquired();
955 957
956 scoped_ptr<OriginalEntries> originals(originals_arg); 958 scoped_ptr<OriginalEntries> originals(originals_arg);
957 const base::TimeDelta elapsed = base::TimeTicks::Now() - time_acquired_; 959 const base::TimeDelta elapsed = base::TimeTicks::Now() - time_acquired_;
958 if (kLoggingInfo && elapsed.InMilliseconds() > 50) { 960 if (kLoggingInfo && elapsed.InMilliseconds() > 50) {
959 logging::LogMessage(source_file_, line_, logging::LOG_INFO).stream() 961 logging::LogMessage(source_file_, line_, logging::LOG_INFO).stream()
960 << name_ << " transaction completed in " << elapsed.InSecondsF() 962 << name_ << " transaction completed in " << elapsed.InSecondsF()
961 << " seconds."; 963 << " seconds.";
962 } 964 }
963 965
964 if (NULL == originals.get() || originals->empty()) { 966 if (NULL == originals.get() || originals->empty()) {
965 dirkernel_->transaction_mutex.Release(); 967 dirkernel_->transaction_mutex.Release();
966 return; 968 return;
967 } 969 }
968 970
969 AutoLock scoped_lock(dirkernel_->changes_channel_mutex); 971 AutoLock scoped_lock(dirkernel_->changes_channel_mutex);
970 // Tell listeners to calculate changes while we still have the mutex. 972 // Tell listeners to calculate changes while we still have the mutex.
971 DirectoryChangeEvent event = { DirectoryChangeEvent::CALCULATE_CHANGES, 973 DirectoryChangeEvent event = { DirectoryChangeEvent::CALCULATE_CHANGES,
972 originals.get(), this, writer_ }; 974 originals.get(), this, writer_ };
973 dirkernel_->changes_channel.Notify(event); 975 dirkernel_->changes_channel.Notify(event);
974 976
977 // Necessary for reads to be performed prior to transaction mutex release.
978 // Allows the listener to use the current transaction to perform reads.
979 DirectoryChangeEvent ending_event =
980 { DirectoryChangeEvent::TRANSACTION_ENDING,
981 NULL, this, INVALID };
982 dirkernel_->changes_channel.Notify(ending_event);
983
975 dirkernel_->transaction_mutex.Release(); 984 dirkernel_->transaction_mutex.Release();
976 985
986 // Directly after transaction mutex release, but lock on changes channel.
987 // You cannot be re-entrant to a transaction in this handler.
977 DirectoryChangeEvent complete_event = 988 DirectoryChangeEvent complete_event =
978 { DirectoryChangeEvent::TRANSACTION_COMPLETE, 989 { DirectoryChangeEvent::TRANSACTION_COMPLETE,
979 NULL, NULL, INVALID }; 990 NULL, NULL, INVALID };
980 dirkernel_->changes_channel.Notify(complete_event); 991 dirkernel_->changes_channel.Notify(complete_event);
981 } 992 }
982 993
983 ReadTransaction::ReadTransaction(Directory* directory, const char* file, 994 ReadTransaction::ReadTransaction(Directory* directory, const char* file,
984 int line) 995 int line)
985 : BaseTransaction(directory, "Read", file, line, INVALID) { 996 : BaseTransaction(directory, "Read", file, line, INVALID) {
986 } 997 }
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 return s << std::dec; 1569 return s << std::dec;
1559 } 1570 }
1560 1571
1561 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) { 1572 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) {
1562 if (blob.empty()) 1573 if (blob.empty())
1563 return dump; 1574 return dump;
1564 string buffer(HexEncode(&blob[0], blob.size())); 1575 string buffer(HexEncode(&blob[0], blob.size()));
1565 dump.out_->sputn(buffer.c_str(), buffer.size()); 1576 dump.out_->sputn(buffer.c_str(), buffer.size());
1566 return dump; 1577 return dump;
1567 } 1578 }
OLDNEW
« chrome/browser/sync/engine/syncapi.cc ('K') | « chrome/browser/sync/syncable/syncable.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698