From d825fc70d4995527a8daebc64c51515baf2670ad Mon Sep 17 00:00:00 2001 From: Andrew Kryczka Date: Thu, 18 Feb 2016 18:03:53 -0800 Subject: [PATCH] Use condition variable in log roller test Summary: Previously I just slept until the flush_thread was "probably" ready since proper synchronization in test cases seemed like overkill. But then tsan complained about it, so I did the synchronization (mostly) properly now. Test Plan: $ COMPILE_WITH_TSAN=1 make -j32 auto_roll_logger_test $ ./auto_roll_logger_test Reviewers: anthony, IslamAbdelRahman, sdong Reviewed By: sdong Subscribers: dhruba, leveldb Differential Revision: https://reviews.facebook.net/D54399 --- db/auto_roll_logger_test.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/db/auto_roll_logger_test.cc b/db/auto_roll_logger_test.cc index 0be5b113b..814a29b08 100644 --- a/db/auto_roll_logger_test.cc +++ b/db/auto_roll_logger_test.cc @@ -12,6 +12,8 @@ #include #include #include "db/auto_roll_logger.h" +#include "port/port.h" +#include "util/mutexlock.h" #include "util/sync_point.h" #include "util/testharness.h" #include "rocksdb/db.h" @@ -291,20 +293,33 @@ TEST_F(AutoRollLoggerTest, LogFlushWhileRolling) { "PosixLogger::Flush:2"}, }); }); + + port::Mutex flush_thread_mutex; + port::CondVar flush_thread_cv{&flush_thread_mutex}; std::thread flush_thread; // Additionally, to exercise the edge case, we need to ensure the old logger // is used. For this, we pause after pinning the logger until dependencies // have probably been loaded. + const int kWaitForDepsSeconds = 1; rocksdb::SyncPoint::GetInstance()->SetCallBack( "AutoRollLogger::Flush:PinnedLogger", [&](void* arg) { + MutexLock ml{&flush_thread_mutex}; + while (flush_thread.get_id() == std::thread::id()) { + flush_thread_cv.Wait(); + } if (std::this_thread::get_id() == flush_thread.get_id()) { - sleep(2); + Env::Default()->SleepForMicroseconds(kWaitForDepsSeconds * 1000 * 1000); + sleep(1); } }); rocksdb::SyncPoint::GetInstance()->EnableProcessing(); - flush_thread = std::thread([&]() { auto_roll_logger->Flush(); }); - sleep(1); + { + MutexLock ml{&flush_thread_mutex}; + flush_thread = std::thread([&]() { auto_roll_logger->Flush(); }); + flush_thread_cv.Signal(); + } + RollLogFileBySizeTest(auto_roll_logger, options.max_log_file_size, kSampleMessage + ":LogFlushWhileRolling"); flush_thread.join();