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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 } |
OLD | NEW |