Internal cleanup PiperOrigin-RevId: 1001893419
diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index 63da068..a84fc96 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc
@@ -51,9 +51,9 @@ void Notification::WaitForNotification() const { base_internal::TraceWait(this, TraceObjectKind()); if (!HasBeenNotifiedInternal(&this->notified_yet_)) { - this->mutex_.LockWhen( + this->mutex_.ReaderLockWhen( Condition(&HasBeenNotifiedInternal, &this->notified_yet_)); - this->mutex_.unlock(); + this->mutex_.unlock_shared(); } base_internal::TraceContinue(this, TraceObjectKind()); } @@ -63,9 +63,9 @@ base_internal::TraceWait(this, TraceObjectKind()); bool notified = HasBeenNotifiedInternal(&this->notified_yet_); if (!notified) { - notified = this->mutex_.LockWhenWithTimeout( + notified = this->mutex_.ReaderLockWhenWithTimeout( Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout); - this->mutex_.unlock(); + this->mutex_.unlock_shared(); } base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind()); return notified; @@ -75,9 +75,9 @@ base_internal::TraceWait(this, TraceObjectKind()); bool notified = HasBeenNotifiedInternal(&this->notified_yet_); if (!notified) { - notified = this->mutex_.LockWhenWithDeadline( + notified = this->mutex_.ReaderLockWhenWithDeadline( Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline); - this->mutex_.unlock(); + this->mutex_.unlock_shared(); } base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind()); return notified;
diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index ded80a5..e2a6c93 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc
@@ -139,6 +139,41 @@ BasicTests(true, &local_notification2); } +TEST(NotificationTest, MultipleWaitersAndDestructionAfterWait) { + constexpr int kNumWaiters = 16; + auto* notification = new Notification(); + ThreadSafeCounter ready_counter; + ThreadSafeCounter done_counter; + + std::vector<std::thread> waiters; + waiters.reserve(kNumWaiters); + for (int i = 0; i < kNumWaiters; ++i) { + waiters.emplace_back([i, notification, &ready_counter, &done_counter]() { + ready_counter.Increment(); + if (i % 3 == 0) { + notification->WaitForNotification(); + } else if (i % 3 == 1) { + EXPECT_TRUE( + notification->WaitForNotificationWithTimeout(absl::Seconds(60))); + } else { + EXPECT_TRUE(notification->WaitForNotificationWithDeadline( + absl::Now() + absl::Seconds(60))); + } + done_counter.Increment(); + }); + } + + ready_counter.WaitUntilGreaterOrEqual(kNumWaiters); + std::thread notifier([notification]() { notification->Notify(); }); + done_counter.WaitUntilGreaterOrEqual(kNumWaiters); + delete notification; + + notifier.join(); + for (std::thread& waiter : waiters) { + waiter.join(); + } +} + #if ABSL_HAVE_ATTRIBUTE_WEAK namespace base_internal {