OLD | NEW |
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 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 } | 953 } |
954 } | 954 } |
955 | 955 |
956 BaseTransaction::BaseTransaction(Directory* directory, const char* name, | 956 BaseTransaction::BaseTransaction(Directory* directory, const char* name, |
957 const char* source_file, int line, WriterTag writer) | 957 const char* source_file, int line, WriterTag writer) |
958 : directory_(directory), dirkernel_(directory->kernel_), name_(name), | 958 : directory_(directory), dirkernel_(directory->kernel_), name_(name), |
959 source_file_(source_file), line_(line), writer_(writer) { | 959 source_file_(source_file), line_(line), writer_(writer) { |
960 Lock(); | 960 Lock(); |
961 } | 961 } |
962 | 962 |
| 963 BaseTransaction::~BaseTransaction() {} |
| 964 |
963 void BaseTransaction::UnlockAndLog(OriginalEntries* originals_arg) { | 965 void BaseTransaction::UnlockAndLog(OriginalEntries* originals_arg) { |
964 dirkernel_->transaction_mutex.AssertAcquired(); | 966 dirkernel_->transaction_mutex.AssertAcquired(); |
965 | 967 |
966 scoped_ptr<OriginalEntries> originals(originals_arg); | 968 scoped_ptr<OriginalEntries> originals(originals_arg); |
967 const base::TimeDelta elapsed = base::TimeTicks::Now() - time_acquired_; | 969 const base::TimeDelta elapsed = base::TimeTicks::Now() - time_acquired_; |
968 if (kLoggingInfo && elapsed.InMilliseconds() > 50) { | 970 if (kLoggingInfo && elapsed.InMilliseconds() > 50) { |
969 logging::LogMessage(source_file_, line_, logging::LOG_INFO).stream() | 971 logging::LogMessage(source_file_, line_, logging::LOG_INFO).stream() |
970 << name_ << " transaction completed in " << elapsed.InSecondsF() | 972 << name_ << " transaction completed in " << elapsed.InSecondsF() |
971 << " seconds."; | 973 << " seconds."; |
972 } | 974 } |
973 | 975 |
974 if (NULL == originals.get() || originals->empty()) { | 976 if (NULL == originals.get() || originals->empty()) { |
975 dirkernel_->transaction_mutex.Release(); | 977 dirkernel_->transaction_mutex.Release(); |
976 return; | 978 return; |
977 } | 979 } |
978 | 980 |
979 AutoLock scoped_lock(dirkernel_->changes_channel_mutex); | 981 AutoLock scoped_lock(dirkernel_->changes_channel_mutex); |
980 // Tell listeners to calculate changes while we still have the mutex. | 982 // Tell listeners to calculate changes while we still have the mutex. |
981 DirectoryChangeEvent event = { DirectoryChangeEvent::CALCULATE_CHANGES, | 983 DirectoryChangeEvent event = { DirectoryChangeEvent::CALCULATE_CHANGES, |
982 originals.get(), this, writer_ }; | 984 originals.get(), this, writer_ }; |
983 dirkernel_->changes_channel.Notify(event); | 985 dirkernel_->changes_channel.Notify(event); |
984 | 986 |
| 987 // Necessary for reads to be performed prior to transaction mutex release. |
| 988 // Allows the listener to use the current transaction to perform reads. |
| 989 DirectoryChangeEvent ending_event = |
| 990 { DirectoryChangeEvent::TRANSACTION_ENDING, |
| 991 NULL, this, INVALID }; |
| 992 dirkernel_->changes_channel.Notify(ending_event); |
| 993 |
985 dirkernel_->transaction_mutex.Release(); | 994 dirkernel_->transaction_mutex.Release(); |
986 | 995 |
| 996 // Directly after transaction mutex release, but lock on changes channel. |
| 997 // You cannot be re-entrant to a transaction in this handler. |
987 DirectoryChangeEvent complete_event = | 998 DirectoryChangeEvent complete_event = |
988 { DirectoryChangeEvent::TRANSACTION_COMPLETE, | 999 { DirectoryChangeEvent::TRANSACTION_COMPLETE, |
989 NULL, NULL, INVALID }; | 1000 NULL, NULL, INVALID }; |
990 dirkernel_->changes_channel.Notify(complete_event); | 1001 dirkernel_->changes_channel.Notify(complete_event); |
991 } | 1002 } |
992 | 1003 |
993 ReadTransaction::ReadTransaction(Directory* directory, const char* file, | 1004 ReadTransaction::ReadTransaction(Directory* directory, const char* file, |
994 int line) | 1005 int line) |
995 : BaseTransaction(directory, "Read", file, line, INVALID) { | 1006 : BaseTransaction(directory, "Read", file, line, INVALID) { |
996 } | 1007 } |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 return s << std::dec; | 1579 return s << std::dec; |
1569 } | 1580 } |
1570 | 1581 |
1571 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) { | 1582 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) { |
1572 if (blob.empty()) | 1583 if (blob.empty()) |
1573 return dump; | 1584 return dump; |
1574 string buffer(HexEncode(&blob[0], blob.size())); | 1585 string buffer(HexEncode(&blob[0], blob.size())); |
1575 dump.out_->sputn(buffer.c_str(), buffer.size()); | 1586 dump.out_->sputn(buffer.c_str(), buffer.size()); |
1576 return dump; | 1587 return dump; |
1577 } | 1588 } |
OLD | NEW |