mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
Inline internal usages of Mutex::Lock, etc. in favor of lock.
PiperOrigin-RevId: 789459507 Change-Id: I573dec1c33b047388509cfea129342ea7bdfe494
This commit is contained in:
committed by
Copybara-Service
parent
0f1abc9b73
commit
d473c92b9e
@@ -73,8 +73,8 @@ bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) {
|
||||
// need to acquire these locks themselves.
|
||||
class MutexRelock {
|
||||
public:
|
||||
explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); }
|
||||
~MutexRelock() { mu_.Lock(); }
|
||||
explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.unlock(); }
|
||||
~MutexRelock() { mu_.lock(); }
|
||||
|
||||
MutexRelock(const MutexRelock&) = delete;
|
||||
MutexRelock& operator=(const MutexRelock&) = delete;
|
||||
|
||||
@@ -53,8 +53,11 @@ class FlagRegistry {
|
||||
// Store a flag in this registry. Takes ownership of *flag.
|
||||
void RegisterFlag(CommandLineFlag& flag, const char* filename);
|
||||
|
||||
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
|
||||
void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
|
||||
void lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.lock(); }
|
||||
inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock(); }
|
||||
|
||||
void unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.unlock(); }
|
||||
inline void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { unlock(); }
|
||||
|
||||
// Returns the flag object for the specified name, or nullptr if not found.
|
||||
// Will emit a warning if a 'retired' flag is specified.
|
||||
@@ -87,8 +90,8 @@ namespace {
|
||||
|
||||
class FlagRegistryLock {
|
||||
public:
|
||||
explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); }
|
||||
~FlagRegistryLock() { fr_.Unlock(); }
|
||||
explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.lock(); }
|
||||
~FlagRegistryLock() { fr_.unlock(); }
|
||||
|
||||
private:
|
||||
FlagRegistry& fr_;
|
||||
|
||||
@@ -378,14 +378,14 @@ void CordzInfo::Untrack() {
|
||||
|
||||
void CordzInfo::Lock(MethodIdentifier method)
|
||||
ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) {
|
||||
mutex_.Lock();
|
||||
mutex_.lock();
|
||||
update_tracker_.LossyAdd(method);
|
||||
assert(rep_);
|
||||
}
|
||||
|
||||
void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) {
|
||||
bool tracked = rep_ != nullptr;
|
||||
mutex_.Unlock();
|
||||
mutex_.unlock();
|
||||
if (!tracked) {
|
||||
Untrack();
|
||||
}
|
||||
|
||||
@@ -148,12 +148,12 @@ ABSL_CONST_INIT absl::Mutex early_const_init_mutex(absl::kConstInit);
|
||||
// before the constructors of either grab_lock or check_still_locked are run.)
|
||||
extern absl::Mutex const_init_sanity_mutex;
|
||||
OnConstruction grab_lock([]() ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
const_init_sanity_mutex.Lock();
|
||||
const_init_sanity_mutex.lock();
|
||||
});
|
||||
ABSL_CONST_INIT absl::Mutex const_init_sanity_mutex(absl::kConstInit);
|
||||
OnConstruction check_still_locked([]() ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
const_init_sanity_mutex.AssertHeld();
|
||||
const_init_sanity_mutex.Unlock();
|
||||
const_init_sanity_mutex.unlock();
|
||||
});
|
||||
#endif // defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900)
|
||||
|
||||
|
||||
@@ -2760,7 +2760,7 @@ void CondVar::SignalAll() {
|
||||
void ReleasableMutexLock::Release() {
|
||||
ABSL_RAW_CHECK(this->mu_ != nullptr,
|
||||
"ReleasableMutexLock::Release may only be called once");
|
||||
this->mu_->Unlock();
|
||||
this->mu_->unlock();
|
||||
this->mu_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -599,11 +599,11 @@ class ABSL_SCOPED_LOCKABLE MutexLock {
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
// Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is
|
||||
// Calls `mu->lock()` and returns when that call returns. That is, `*mu` is
|
||||
// guaranteed to be locked when this object is constructed. Requires that
|
||||
// `mu` be dereferenceable.
|
||||
explicit MutexLock(Mutex& mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
|
||||
this->mu_.Lock();
|
||||
this->mu_.lock();
|
||||
}
|
||||
|
||||
explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
|
||||
@@ -623,7 +623,7 @@ class ABSL_SCOPED_LOCKABLE MutexLock {
|
||||
MutexLock& operator=(const MutexLock&) = delete;
|
||||
MutexLock& operator=(MutexLock&&) = delete;
|
||||
|
||||
~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.Unlock(); }
|
||||
~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.unlock(); }
|
||||
|
||||
private:
|
||||
Mutex& mu_;
|
||||
@@ -657,7 +657,7 @@ class ABSL_SCOPED_LOCKABLE ReaderMutexLock {
|
||||
ReaderMutexLock& operator=(const ReaderMutexLock&) = delete;
|
||||
ReaderMutexLock& operator=(ReaderMutexLock&&) = delete;
|
||||
|
||||
~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.ReaderUnlock(); }
|
||||
~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.unlock_shared(); }
|
||||
|
||||
private:
|
||||
Mutex& mu_;
|
||||
@@ -1049,7 +1049,7 @@ class ABSL_SCOPED_LOCKABLE MutexLockMaybe {
|
||||
ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
|
||||
: mu_(mu) {
|
||||
if (this->mu_ != nullptr) {
|
||||
this->mu_->Lock();
|
||||
this->mu_->lock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,7 +1063,7 @@ class ABSL_SCOPED_LOCKABLE MutexLockMaybe {
|
||||
|
||||
~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() {
|
||||
if (this->mu_ != nullptr) {
|
||||
this->mu_->Unlock();
|
||||
this->mu_->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ class ABSL_SCOPED_LOCKABLE ReleasableMutexLock {
|
||||
explicit ReleasableMutexLock(Mutex* absl_nonnull mu)
|
||||
ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
|
||||
: mu_(mu) {
|
||||
this->mu_->Lock();
|
||||
this->mu_->lock();
|
||||
}
|
||||
|
||||
explicit ReleasableMutexLock(Mutex* absl_nonnull mu, const Condition& cond)
|
||||
@@ -1095,7 +1095,7 @@ class ABSL_SCOPED_LOCKABLE ReleasableMutexLock {
|
||||
|
||||
~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() {
|
||||
if (this->mu_ != nullptr) {
|
||||
this->mu_->Unlock();
|
||||
this->mu_->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ BENCHMARK(BM_ReaderLock)->UseRealTime()->Threads(1)->ThreadPerCpu();
|
||||
void BM_TryLock(benchmark::State& state) {
|
||||
absl::Mutex mu;
|
||||
for (auto _ : state) {
|
||||
if (mu.TryLock()) {
|
||||
mu.Unlock();
|
||||
if (mu.try_lock()) {
|
||||
mu.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,8 +56,8 @@ BENCHMARK(BM_TryLock);
|
||||
void BM_ReaderTryLock(benchmark::State& state) {
|
||||
static absl::NoDestructor<absl::Mutex> mu;
|
||||
for (auto _ : state) {
|
||||
if (mu->ReaderTryLock()) {
|
||||
mu->ReaderUnlock();
|
||||
if (mu->try_lock_shared()) {
|
||||
mu->unlock_shared();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ void BM_ConditionWaiters(benchmark::State& state) {
|
||||
init->DecrementCount();
|
||||
m->LockWhen(absl::Condition(
|
||||
static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p));
|
||||
m->Unlock();
|
||||
m->unlock();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,15 +299,15 @@ void BM_ConditionWaiters(benchmark::State& state) {
|
||||
init.Wait();
|
||||
|
||||
for (auto _ : state) {
|
||||
mu.Lock();
|
||||
mu.Unlock(); // Each unlock requires Condition evaluation for our waiters.
|
||||
mu.lock();
|
||||
mu.unlock(); // Each unlock requires Condition evaluation for our waiters.
|
||||
}
|
||||
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
for (int i = 0; i < num_classes; i++) {
|
||||
equivalence_classes[i] = 0;
|
||||
}
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
}
|
||||
|
||||
// Some configurations have higher thread limits than others.
|
||||
|
||||
@@ -119,11 +119,11 @@ static void TestTry(TestContext *cxt, int c) {
|
||||
for (int i = 0; i != cxt->iterations; i++) {
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
} while (!cxt->mu.TryLock());
|
||||
} while (!cxt->mu.try_lock());
|
||||
int a = cxt->g0 + 1;
|
||||
cxt->g0 = a;
|
||||
cxt->g1--;
|
||||
cxt->mu.Unlock();
|
||||
cxt->mu.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,9 +353,9 @@ static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }
|
||||
|
||||
static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
|
||||
const std::function<void(int)> &cb) {
|
||||
mu->Lock();
|
||||
mu->lock();
|
||||
int c = (*c0)++;
|
||||
mu->Unlock();
|
||||
mu->unlock();
|
||||
cb(c);
|
||||
absl::MutexLock l(mu);
|
||||
(*c1)++;
|
||||
@@ -379,11 +379,11 @@ static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
|
||||
&EndTest, &c0, &c1, &mu2, &cv2,
|
||||
std::function<void(int)>(std::bind(test, cxt, std::placeholders::_1))));
|
||||
}
|
||||
mu2.Lock();
|
||||
mu2.lock();
|
||||
while (c1 != threads) {
|
||||
cv2.Wait(&mu2);
|
||||
}
|
||||
mu2.Unlock();
|
||||
mu2.unlock();
|
||||
return cxt->g0;
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ struct TimeoutBugStruct {
|
||||
static void WaitForA(TimeoutBugStruct *x) {
|
||||
x->mu.LockWhen(absl::Condition(&x->a));
|
||||
x->a_waiter_count--;
|
||||
x->mu.Unlock();
|
||||
x->mu.unlock();
|
||||
}
|
||||
|
||||
static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }
|
||||
@@ -447,27 +447,27 @@ TEST(Mutex, CondVarWaitSignalsAwait) {
|
||||
// Thread A. Sets barrier, waits for release using Mutex::Await, then
|
||||
// signals released_cv.
|
||||
pool->Schedule([&state] {
|
||||
state.release_mu.Lock();
|
||||
state.release_mu.lock();
|
||||
|
||||
state.barrier_mu.Lock();
|
||||
state.barrier_mu.lock();
|
||||
state.barrier = true;
|
||||
state.barrier_mu.Unlock();
|
||||
state.barrier_mu.unlock();
|
||||
|
||||
state.release_mu.Await(absl::Condition(&state.release));
|
||||
state.released_cv.Signal();
|
||||
state.release_mu.Unlock();
|
||||
state.release_mu.unlock();
|
||||
});
|
||||
|
||||
state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
|
||||
state.barrier_mu.Unlock();
|
||||
state.release_mu.Lock();
|
||||
state.barrier_mu.unlock();
|
||||
state.release_mu.lock();
|
||||
// Thread A is now blocked on release by way of Mutex::Await().
|
||||
|
||||
// Set release. Calling released_cv.Wait() should un-block thread A,
|
||||
// which will signal released_cv. If not, the test will hang.
|
||||
state.release = true;
|
||||
state.released_cv.Wait(&state.release_mu);
|
||||
state.release_mu.Unlock();
|
||||
state.release_mu.unlock();
|
||||
}
|
||||
|
||||
// Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
|
||||
@@ -488,20 +488,20 @@ TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
|
||||
// Thread A. Sets barrier, waits for release using Mutex::Await, then
|
||||
// signals released_cv.
|
||||
pool->Schedule([&state] {
|
||||
state.release_mu.Lock();
|
||||
state.release_mu.lock();
|
||||
|
||||
state.barrier_mu.Lock();
|
||||
state.barrier_mu.lock();
|
||||
state.barrier = true;
|
||||
state.barrier_mu.Unlock();
|
||||
state.barrier_mu.unlock();
|
||||
|
||||
state.release_mu.Await(absl::Condition(&state.release));
|
||||
state.released_cv.Signal();
|
||||
state.release_mu.Unlock();
|
||||
state.release_mu.unlock();
|
||||
});
|
||||
|
||||
state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
|
||||
state.barrier_mu.Unlock();
|
||||
state.release_mu.Lock();
|
||||
state.barrier_mu.unlock();
|
||||
state.release_mu.lock();
|
||||
// Thread A is now blocked on release by way of Mutex::Await().
|
||||
|
||||
// Set release. Calling released_cv.Wait() should un-block thread A,
|
||||
@@ -512,7 +512,7 @@ TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
|
||||
<< "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
|
||||
"unblock the absl::Mutex::Await call in another thread.";
|
||||
|
||||
state.release_mu.Unlock();
|
||||
state.release_mu.unlock();
|
||||
}
|
||||
|
||||
// Test for regression of a bug in loop of TryRemove()
|
||||
@@ -538,7 +538,7 @@ TEST(Mutex, MutexTimeoutBug) {
|
||||
|
||||
x.a = true; // wakeup the two waiters on A
|
||||
x.mu.Await(absl::Condition(&NoAWaiters, &x)); // wait for them to exit
|
||||
x.mu.Unlock();
|
||||
x.mu.unlock();
|
||||
}
|
||||
|
||||
struct CondVarWaitDeadlock : testing::TestWithParam<int> {
|
||||
@@ -558,27 +558,27 @@ struct CondVarWaitDeadlock : testing::TestWithParam<int> {
|
||||
|
||||
void Waiter1() {
|
||||
if (read_lock1) {
|
||||
mu.ReaderLock();
|
||||
mu.lock_shared();
|
||||
while (!cond1) {
|
||||
cv.Wait(&mu);
|
||||
}
|
||||
mu.ReaderUnlock();
|
||||
mu.unlock_shared();
|
||||
} else {
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
while (!cond1) {
|
||||
cv.Wait(&mu);
|
||||
}
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void Waiter2() {
|
||||
if (read_lock2) {
|
||||
mu.ReaderLockWhen(absl::Condition(&cond2));
|
||||
mu.ReaderUnlock();
|
||||
mu.unlock_shared();
|
||||
} else {
|
||||
mu.LockWhen(absl::Condition(&cond2));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -602,21 +602,21 @@ TEST_P(CondVarWaitDeadlock, Test) {
|
||||
absl::SleepFor(absl::Milliseconds(100));
|
||||
|
||||
// Wake condwaiter.
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
cond1 = true;
|
||||
if (signal_unlocked) {
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
cv.Signal();
|
||||
} else {
|
||||
cv.Signal();
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
}
|
||||
waiter1.reset(); // "join" waiter1
|
||||
|
||||
// Wake waiter.
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
cond2 = true;
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
waiter2.reset(); // "join" waiter2
|
||||
}
|
||||
|
||||
@@ -641,19 +641,19 @@ struct DequeueAllWakeableBugStruct {
|
||||
|
||||
// Test for regression of a bug in loop of DequeueAllWakeable()
|
||||
static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
|
||||
x->mu.ReaderLock();
|
||||
x->mu2.Lock();
|
||||
x->mu.lock_shared();
|
||||
x->mu2.lock();
|
||||
x->unfinished_count--;
|
||||
x->done1 = (x->unfinished_count == 0);
|
||||
x->mu2.Unlock();
|
||||
x->mu2.unlock();
|
||||
// make sure that both readers acquired mu before we release it.
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
x->mu.ReaderUnlock();
|
||||
x->mu.unlock_shared();
|
||||
|
||||
x->mu2.Lock();
|
||||
x->mu2.lock();
|
||||
x->finished_count--;
|
||||
x->done2 = (x->finished_count == 0);
|
||||
x->mu2.Unlock();
|
||||
x->mu2.unlock();
|
||||
}
|
||||
|
||||
// Test for regression of a bug in loop of DequeueAllWakeable()
|
||||
@@ -665,21 +665,21 @@ TEST(Mutex, MutexReaderWakeupBug) {
|
||||
x.done1 = false;
|
||||
x.finished_count = 2;
|
||||
x.done2 = false;
|
||||
x.mu.Lock(); // acquire mu exclusively
|
||||
x.mu.lock(); // acquire mu exclusively
|
||||
// queue two thread that will block on reader locks on x.mu
|
||||
tp->Schedule(std::bind(&AcquireAsReader, &x));
|
||||
tp->Schedule(std::bind(&AcquireAsReader, &x));
|
||||
absl::SleepFor(absl::Seconds(1)); // give time for reader threads to block
|
||||
x.mu.Unlock(); // wake them up
|
||||
x.mu.unlock(); // wake them up
|
||||
|
||||
// both readers should finish promptly
|
||||
EXPECT_TRUE(
|
||||
x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
|
||||
x.mu2.Unlock();
|
||||
x.mu2.unlock();
|
||||
|
||||
EXPECT_TRUE(
|
||||
x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
|
||||
x.mu2.Unlock();
|
||||
x.mu2.unlock();
|
||||
}
|
||||
|
||||
struct LockWhenTestStruct {
|
||||
@@ -691,15 +691,15 @@ struct LockWhenTestStruct {
|
||||
};
|
||||
|
||||
static bool LockWhenTestIsCond(LockWhenTestStruct *s) {
|
||||
s->mu2.Lock();
|
||||
s->mu2.lock();
|
||||
s->waiting = true;
|
||||
s->mu2.Unlock();
|
||||
s->mu2.unlock();
|
||||
return s->cond;
|
||||
}
|
||||
|
||||
static void LockWhenTestWaitForIsCond(LockWhenTestStruct *s) {
|
||||
s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
|
||||
s->mu1.Unlock();
|
||||
s->mu1.unlock();
|
||||
}
|
||||
|
||||
TEST(Mutex, LockWhen) {
|
||||
@@ -707,11 +707,11 @@ TEST(Mutex, LockWhen) {
|
||||
|
||||
std::thread t(LockWhenTestWaitForIsCond, &s);
|
||||
s.mu2.LockWhen(absl::Condition(&s.waiting));
|
||||
s.mu2.Unlock();
|
||||
s.mu2.unlock();
|
||||
|
||||
s.mu1.Lock();
|
||||
s.mu1.lock();
|
||||
s.cond = true;
|
||||
s.mu1.Unlock();
|
||||
s.mu1.unlock();
|
||||
|
||||
t.join();
|
||||
}
|
||||
@@ -751,7 +751,7 @@ TEST(Mutex, LockWhenGuard) {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// The following test requires Mutex::ReaderLock to be a real shared
|
||||
// The following test requires Mutex::lock_shared to be a real shared
|
||||
// lock, which is not the case in all builds.
|
||||
#if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
|
||||
|
||||
@@ -778,9 +778,9 @@ struct ReaderDecrementBugStruct {
|
||||
// L >= mu, L < mu_waiting_on_cond
|
||||
static bool IsCond(void *v) {
|
||||
ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
|
||||
x->mu2.Lock();
|
||||
x->mu2.lock();
|
||||
x->waiting_on_cond = true;
|
||||
x->mu2.Unlock();
|
||||
x->mu2.unlock();
|
||||
return x->cond;
|
||||
}
|
||||
|
||||
@@ -796,20 +796,20 @@ static void WaitForCond(ReaderDecrementBugStruct *x) {
|
||||
absl::MutexLock l(dummy);
|
||||
x->mu.LockWhen(absl::Condition(&IsCond, x));
|
||||
x->done--;
|
||||
x->mu.Unlock();
|
||||
x->mu.unlock();
|
||||
}
|
||||
|
||||
// L={}
|
||||
static void GetReadLock(ReaderDecrementBugStruct *x) {
|
||||
x->mu.ReaderLock();
|
||||
x->mu2.Lock();
|
||||
x->mu.lock_shared();
|
||||
x->mu2.lock();
|
||||
x->have_reader_lock = true;
|
||||
x->mu2.Await(absl::Condition(&x->complete));
|
||||
x->mu2.Unlock();
|
||||
x->mu.ReaderUnlock();
|
||||
x->mu.Lock();
|
||||
x->mu2.unlock();
|
||||
x->mu.unlock_shared();
|
||||
x->mu.lock();
|
||||
x->done--;
|
||||
x->mu.Unlock();
|
||||
x->mu.unlock();
|
||||
}
|
||||
|
||||
// Test for reader counter being decremented incorrectly by waiter
|
||||
@@ -825,32 +825,32 @@ TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
// Run WaitForCond() and wait for it to sleep
|
||||
std::thread thread1(WaitForCond, &x);
|
||||
x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
|
||||
x.mu2.Unlock();
|
||||
x.mu2.unlock();
|
||||
|
||||
// Run GetReadLock(), and wait for it to get the read lock
|
||||
std::thread thread2(GetReadLock, &x);
|
||||
x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
|
||||
x.mu2.Unlock();
|
||||
x.mu2.unlock();
|
||||
|
||||
// Get the reader lock ourselves, and release it.
|
||||
x.mu.ReaderLock();
|
||||
x.mu.ReaderUnlock();
|
||||
x.mu.lock_shared();
|
||||
x.mu.unlock_shared();
|
||||
|
||||
// The lock should be held in read mode by GetReadLock().
|
||||
// If we have the bug, the lock will be free.
|
||||
x.mu.AssertReaderHeld();
|
||||
|
||||
// Wake up all the threads.
|
||||
x.mu2.Lock();
|
||||
x.mu2.lock();
|
||||
x.complete = true;
|
||||
x.mu2.Unlock();
|
||||
x.mu2.unlock();
|
||||
|
||||
// TODO(delesley): turn on analysis once lock upgrading is supported.
|
||||
// (This call upgrades the lock from shared to exclusive.)
|
||||
x.mu.Lock();
|
||||
x.mu.lock();
|
||||
x.cond = true;
|
||||
x.mu.Await(absl::Condition(&AllDone, &x));
|
||||
x.mu.Unlock();
|
||||
x.mu.unlock();
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
@@ -873,7 +873,7 @@ TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
if ((j % 2) == 0) {
|
||||
mu[j].WriterLock();
|
||||
} else {
|
||||
mu[j].ReaderLock();
|
||||
mu[j].lock_shared();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1069,15 +1069,15 @@ static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
|
||||
int *running) {
|
||||
absl::InsecureBitGen gen;
|
||||
std::uniform_int_distribution<int> random_millis(0, 15);
|
||||
mu->ReaderLock();
|
||||
mu->lock_shared();
|
||||
while (*running == 3) {
|
||||
absl::SleepFor(absl::Milliseconds(random_millis(gen)));
|
||||
cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
|
||||
}
|
||||
mu->ReaderUnlock();
|
||||
mu->Lock();
|
||||
mu->unlock_shared();
|
||||
mu->lock();
|
||||
(*running)--;
|
||||
mu->Unlock();
|
||||
mu->unlock();
|
||||
}
|
||||
|
||||
static bool IntIsZero(int *x) { return *x == 0; }
|
||||
@@ -1092,10 +1092,10 @@ TEST(Mutex, TestReaderOnCondVar) {
|
||||
tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
|
||||
tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
running--;
|
||||
mu.Await(absl::Condition(&IntIsZero, &running));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -1119,7 +1119,7 @@ static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
|
||||
bool always_false = false;
|
||||
x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
|
||||
absl::Milliseconds(100));
|
||||
x->mu1.Unlock();
|
||||
x->mu1.unlock();
|
||||
}
|
||||
CHECK_LT(x->value, 4) << "should not be invoked a fourth time";
|
||||
|
||||
@@ -1131,7 +1131,7 @@ static void WaitForCond2(AcquireFromConditionStruct *x) {
|
||||
// wait for cond0 to become true
|
||||
x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
|
||||
x->done = true;
|
||||
x->mu0.Unlock();
|
||||
x->mu0.unlock();
|
||||
}
|
||||
|
||||
// Test for Condition whose function acquires other Mutexes
|
||||
@@ -1147,12 +1147,12 @@ TEST(Mutex, AcquireFromCondition) {
|
||||
// return false.
|
||||
absl::SleepFor(absl::Milliseconds(500)); // allow T time to hang
|
||||
|
||||
x.mu0.Lock();
|
||||
x.mu0.lock();
|
||||
x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500)); // wake T
|
||||
// T will be woken because the Wait() will call ConditionWithAcquire()
|
||||
// for the second time, and it will return true.
|
||||
|
||||
x.mu0.Unlock();
|
||||
x.mu0.unlock();
|
||||
|
||||
// T will then acquire the lock and recheck its own condition.
|
||||
// It will find the condition true, as this is the third invocation,
|
||||
@@ -1168,7 +1168,7 @@ TEST(Mutex, AcquireFromCondition) {
|
||||
// is conceptually waiting both on the condition variable, and on mu2.
|
||||
|
||||
x.mu0.LockWhen(absl::Condition(&x.done));
|
||||
x.mu0.Unlock();
|
||||
x.mu0.unlock();
|
||||
}
|
||||
|
||||
TEST(Mutex, DeadlockDetector) {
|
||||
@@ -1180,20 +1180,20 @@ TEST(Mutex, DeadlockDetector) {
|
||||
absl::Mutex m3;
|
||||
absl::Mutex m4;
|
||||
|
||||
m1.Lock(); // m1 gets ID1
|
||||
m2.Lock(); // m2 gets ID2
|
||||
m3.Lock(); // m3 gets ID3
|
||||
m3.Unlock();
|
||||
m2.Unlock();
|
||||
m1.lock(); // m1 gets ID1
|
||||
m2.lock(); // m2 gets ID2
|
||||
m3.lock(); // m3 gets ID3
|
||||
m3.unlock();
|
||||
m2.unlock();
|
||||
// m1 still held
|
||||
m1.ForgetDeadlockInfo(); // m1 loses ID
|
||||
m2.Lock(); // m2 gets ID2
|
||||
m3.Lock(); // m3 gets ID3
|
||||
m4.Lock(); // m4 gets ID4
|
||||
m3.Unlock();
|
||||
m2.Unlock();
|
||||
m4.Unlock();
|
||||
m1.Unlock();
|
||||
m2.lock(); // m2 gets ID2
|
||||
m3.lock(); // m3 gets ID3
|
||||
m4.lock(); // m4 gets ID4
|
||||
m3.unlock();
|
||||
m2.unlock();
|
||||
m4.unlock();
|
||||
m1.unlock();
|
||||
}
|
||||
|
||||
// Bazel has a test "warning" file that programs can write to if the
|
||||
@@ -1248,18 +1248,18 @@ TEST(Mutex, DeadlockDetectorBazelWarning) {
|
||||
|
||||
absl::Mutex mu0;
|
||||
absl::Mutex mu1;
|
||||
bool got_mu0 = mu0.TryLock();
|
||||
mu1.Lock(); // acquire mu1 while holding mu0
|
||||
bool got_mu0 = mu0.try_lock();
|
||||
mu1.lock(); // acquire mu1 while holding mu0
|
||||
if (got_mu0) {
|
||||
mu0.Unlock();
|
||||
mu0.unlock();
|
||||
}
|
||||
if (mu0.TryLock()) { // try lock shouldn't cause deadlock detector to fire
|
||||
mu0.Unlock();
|
||||
if (mu0.try_lock()) { // try lock shouldn't cause deadlock detector to fire
|
||||
mu0.unlock();
|
||||
}
|
||||
mu0.Lock(); // acquire mu0 while holding mu1; should get one deadlock
|
||||
mu0.lock(); // acquire mu0 while holding mu1; should get one deadlock
|
||||
// report here
|
||||
mu0.Unlock();
|
||||
mu1.Unlock();
|
||||
mu0.unlock();
|
||||
mu1.unlock();
|
||||
|
||||
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
|
||||
}
|
||||
@@ -1274,10 +1274,10 @@ TEST(Mutex, DeadlockDetectorLongCycle) {
|
||||
// Check that we survive a deadlock with a lock cycle.
|
||||
std::vector<absl::Mutex> mutex(100);
|
||||
for (size_t i = 0; i != mutex.size(); i++) {
|
||||
mutex[i].Lock();
|
||||
mutex[(i + 1) % mutex.size()].Lock();
|
||||
mutex[i].Unlock();
|
||||
mutex[(i + 1) % mutex.size()].Unlock();
|
||||
mutex[i].lock();
|
||||
mutex[(i + 1) % mutex.size()].lock();
|
||||
mutex[i].unlock();
|
||||
mutex[(i + 1) % mutex.size()].unlock();
|
||||
}
|
||||
|
||||
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
|
||||
@@ -1297,10 +1297,10 @@ TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
int end = std::min(n_locks, i + 5);
|
||||
// acquire and then release locks i, i+1, ..., i+4
|
||||
for (int j = i; j < end; j++) {
|
||||
array_of_locks[j].Lock();
|
||||
array_of_locks[j].lock();
|
||||
}
|
||||
for (int j = i; j < end; j++) {
|
||||
array_of_locks[j].Unlock();
|
||||
array_of_locks[j].unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1321,11 +1321,11 @@ TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
absl::Mutex b, c;
|
||||
|
||||
// Hold mutex.
|
||||
a->Lock();
|
||||
a->lock();
|
||||
|
||||
// Force deadlock id assignment by acquiring another lock.
|
||||
b.Lock();
|
||||
b.Unlock();
|
||||
b.lock();
|
||||
b.unlock();
|
||||
|
||||
// Delete the mutex. The Mutex destructor tries to remove held locks,
|
||||
// but the attempt isn't foolproof. It can fail if:
|
||||
@@ -1340,8 +1340,8 @@ TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
// We should end up getting assigned the same deadlock id that was
|
||||
// freed up when "a" was deleted, which will cause a spurious deadlock
|
||||
// report if the held lock entry for "a" was not invalidated.
|
||||
c.Lock();
|
||||
c.Unlock();
|
||||
c.lock();
|
||||
c.unlock();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -1620,7 +1620,7 @@ TEST_P(TimeoutTest, LockWhen) {
|
||||
params.use_absolute_deadline
|
||||
? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
|
||||
: mu.LockWhenWithTimeout(cond, params.wait_timeout);
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
|
||||
if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
|
||||
EXPECT_EQ(params.expected_result, result);
|
||||
@@ -1656,7 +1656,7 @@ TEST_P(TimeoutTest, ReaderLockWhen) {
|
||||
start_time + params.wait_timeout)
|
||||
: mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
|
||||
params.wait_timeout);
|
||||
mu.ReaderUnlock();
|
||||
mu.unlock_shared();
|
||||
|
||||
if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
|
||||
EXPECT_EQ(params.expected_result, result);
|
||||
@@ -1713,13 +1713,13 @@ TEST(Mutex, Logging) {
|
||||
logged_mutex.EnableDebugLog("fido_mutex");
|
||||
absl::CondVar logged_cv;
|
||||
logged_cv.EnableDebugLog("rover_cv");
|
||||
logged_mutex.Lock();
|
||||
logged_mutex.lock();
|
||||
logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
|
||||
logged_mutex.Unlock();
|
||||
logged_mutex.ReaderLock();
|
||||
logged_mutex.ReaderUnlock();
|
||||
logged_mutex.Lock();
|
||||
logged_mutex.Unlock();
|
||||
logged_mutex.unlock();
|
||||
logged_mutex.lock_shared();
|
||||
logged_mutex.unlock_shared();
|
||||
logged_mutex.lock();
|
||||
logged_mutex.unlock();
|
||||
logged_cv.Signal();
|
||||
logged_cv.SignalAll();
|
||||
}
|
||||
@@ -1737,8 +1737,8 @@ TEST(Mutex, LoggingAddressReuse) {
|
||||
alive[i] = true;
|
||||
mu->EnableDebugLog("Mutex");
|
||||
mu->EnableInvariantDebugging(invariant, &alive[i]);
|
||||
mu->Lock();
|
||||
mu->Unlock();
|
||||
mu->lock();
|
||||
mu->unlock();
|
||||
mu->~Mutex();
|
||||
alive[i] = false;
|
||||
}
|
||||
@@ -1764,8 +1764,8 @@ TEST(Mutex, SynchEventRace) {
|
||||
{
|
||||
absl::Mutex mu;
|
||||
mu.EnableInvariantDebugging([](void *) {}, nullptr);
|
||||
mu.Lock();
|
||||
mu.Unlock();
|
||||
mu.lock();
|
||||
mu.unlock();
|
||||
}
|
||||
{
|
||||
absl::Mutex mu;
|
||||
@@ -1902,7 +1902,7 @@ TEST(Mutex, MuTime) {
|
||||
}
|
||||
|
||||
TEST(Mutex, SignalExitedThread) {
|
||||
// The test may expose a race when Mutex::Unlock signals a thread
|
||||
// The test may expose a race when Mutex::unlock signals a thread
|
||||
// that has already exited.
|
||||
#if defined(__wasm__) || defined(__asmjs__)
|
||||
constexpr int kThreads = 1; // OOMs under WASM
|
||||
@@ -1915,11 +1915,11 @@ TEST(Mutex, SignalExitedThread) {
|
||||
for (int i = 0; i < kThreads; i++) {
|
||||
absl::Mutex mu;
|
||||
std::thread t([&]() {
|
||||
mu.Lock();
|
||||
mu.Unlock();
|
||||
mu.lock();
|
||||
mu.unlock();
|
||||
});
|
||||
mu.Lock();
|
||||
mu.Unlock();
|
||||
mu.lock();
|
||||
mu.unlock();
|
||||
t.join();
|
||||
}
|
||||
});
|
||||
@@ -1980,30 +1980,30 @@ TEST(Mutex, CondVarPriority) {
|
||||
bool morph = false;
|
||||
std::thread th([&]() {
|
||||
EXPECT_EQ(0, pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m));
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
locked = true;
|
||||
mu.Await(absl::Condition(¬ified));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
EXPECT_EQ(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
|
||||
->per_thread_synch.priority,
|
||||
param.sched_priority);
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
mu.Await(absl::Condition(&waiting));
|
||||
morph = true;
|
||||
absl::SleepFor(absl::Seconds(1));
|
||||
cv.Signal();
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
});
|
||||
mu.Lock();
|
||||
mu.lock();
|
||||
mu.Await(absl::Condition(&locked));
|
||||
notified = true;
|
||||
mu.Unlock();
|
||||
mu.Lock();
|
||||
mu.unlock();
|
||||
mu.lock();
|
||||
waiting = true;
|
||||
while (!morph) {
|
||||
cv.Wait(&mu);
|
||||
}
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
th.join();
|
||||
EXPECT_NE(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
|
||||
->per_thread_synch.priority,
|
||||
@@ -2018,20 +2018,20 @@ TEST(Mutex, LockWhenWithTimeoutResult) {
|
||||
const bool kAlwaysTrue = true, kAlwaysFalse = false;
|
||||
const absl::Condition kTrueCond(&kAlwaysTrue), kFalseCond(&kAlwaysFalse);
|
||||
EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
|
||||
EXPECT_TRUE(mu.AwaitWithTimeout(kTrueCond, absl::Milliseconds(1)));
|
||||
EXPECT_FALSE(mu.AwaitWithTimeout(kFalseCond, absl::Milliseconds(1)));
|
||||
std::thread th1([&]() {
|
||||
EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
});
|
||||
std::thread th2([&]() {
|
||||
EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
});
|
||||
absl::SleepFor(absl::Milliseconds(100));
|
||||
mu.Unlock();
|
||||
mu.unlock();
|
||||
th1.join();
|
||||
th2.join();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ void Notification::WaitForNotification() const {
|
||||
if (!HasBeenNotifiedInternal(&this->notified_yet_)) {
|
||||
this->mutex_.LockWhen(
|
||||
Condition(&HasBeenNotifiedInternal, &this->notified_yet_));
|
||||
this->mutex_.Unlock();
|
||||
this->mutex_.unlock();
|
||||
}
|
||||
base_internal::TraceContinue(this, TraceObjectKind());
|
||||
}
|
||||
@@ -63,7 +63,7 @@ bool Notification::WaitForNotificationWithTimeout(
|
||||
if (!notified) {
|
||||
notified = this->mutex_.LockWhenWithTimeout(
|
||||
Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout);
|
||||
this->mutex_.Unlock();
|
||||
this->mutex_.unlock();
|
||||
}
|
||||
base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind());
|
||||
return notified;
|
||||
@@ -75,7 +75,7 @@ bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const {
|
||||
if (!notified) {
|
||||
notified = this->mutex_.LockWhenWithDeadline(
|
||||
Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline);
|
||||
this->mutex_.Unlock();
|
||||
this->mutex_.unlock();
|
||||
}
|
||||
base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind());
|
||||
return notified;
|
||||
|
||||
Reference in New Issue
Block a user