Fix TSAN caused by calling rend() and pop_front(). (#9698)

Summary:
PR9686 makes `WriteToWAL()` call `assert(...!=rend())` while not holding
db mutex or log mutex. Another thread may concurrently call
`pop_front()`, causing race condition.
To fix, assert only if mutex is held.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/9698

Test Plan: COMPILE_WITH_TSAN=1 make check

Reviewed By: jay-zhuang

Differential Revision: D34898535

Pulled By: riversand963

fbshipit-source-id: 1ddfa5bf1b6ae8d409cab6ff6e1b5321c6803da9
This commit is contained in:
Yanqin Jin 2022-03-15 12:16:40 -07:00 committed by Facebook GitHub Bot
parent 60422f1676
commit 6a76008369

View File

@ -1183,10 +1183,6 @@ IOStatus DBImpl::WriteToWAL(const WriteBatch& merged_batch,
assert(with_log_mutex); assert(with_log_mutex);
} }
#ifdef NDEBUG
(void)with_log_mutex;
#endif
Slice log_entry = WriteBatchInternal::Contents(&merged_batch); Slice log_entry = WriteBatchInternal::Contents(&merged_batch);
*log_size = log_entry.size(); *log_size = log_entry.size();
// When two_write_queues_ WriteToWAL has to be protected from concurretn calls // When two_write_queues_ WriteToWAL has to be protected from concurretn calls
@ -1214,13 +1210,15 @@ IOStatus DBImpl::WriteToWAL(const WriteBatch& merged_batch,
if (with_db_mutex || with_log_mutex) { if (with_db_mutex || with_log_mutex) {
#endif // __has_feature(thread_sanitizer) #endif // __has_feature(thread_sanitizer)
#endif // defined(__has_feature) #endif // defined(__has_feature)
assert(alive_log_files_tail_ != alive_log_files_.rend());
assert(alive_log_files_tail_ == alive_log_files_.rbegin()); assert(alive_log_files_tail_ == alive_log_files_.rbegin());
#if defined(__has_feature) #if defined(__has_feature)
#if __has_feature(thread_sanitizer) #if __has_feature(thread_sanitizer)
} }
#endif // __has_feature(thread_sanitizer) #endif // __has_feature(thread_sanitizer)
#endif // defined(__has_feature) #endif // defined(__has_feature)
if (with_db_mutex || with_log_mutex) {
assert(alive_log_files_tail_ != alive_log_files_.rend());
}
LogFileNumberSize& last_alive_log = *alive_log_files_tail_; LogFileNumberSize& last_alive_log = *alive_log_files_tail_;
last_alive_log.AddSize(*log_size); last_alive_log.AddSize(*log_size);
log_empty_ = false; log_empty_ = false;