notification.cc
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "absl/synchronization/notification.h"
00016 
00017 #include <atomic>
00018 
00019 #include "absl/base/attributes.h"
00020 #include "absl/base/internal/raw_logging.h"
00021 #include "absl/synchronization/mutex.h"
00022 #include "absl/time/time.h"
00023 
00024 namespace absl {
00025 
00026 void Notification::Notify() {
00027   MutexLock l(&this->mutex_);
00028 
00029 #ifndef NDEBUG
00030   if (ABSL_PREDICT_FALSE(notified_yet_.load(std::memory_order_relaxed))) {
00031     ABSL_RAW_LOG(
00032         FATAL,
00033         "Notify() method called more than once for Notification object %p",
00034         static_cast<void *>(this));
00035   }
00036 #endif
00037 
00038   notified_yet_.store(true, std::memory_order_release);
00039 }
00040 
00041 Notification::~Notification() {
00042   // Make sure that the thread running Notify() exits before the object is
00043   // destructed.
00044   MutexLock l(&this->mutex_);
00045 }
00046 
00047 static inline bool HasBeenNotifiedInternal(
00048     const std::atomic<bool> *notified_yet) {
00049   return notified_yet->load(std::memory_order_acquire);
00050 }
00051 
00052 bool Notification::HasBeenNotified() const {
00053   return HasBeenNotifiedInternal(&this->notified_yet_);
00054 }
00055 
00056 void Notification::WaitForNotification() const {
00057   if (!HasBeenNotifiedInternal(&this->notified_yet_)) {
00058     this->mutex_.LockWhen(Condition(&HasBeenNotifiedInternal,
00059                                     &this->notified_yet_));
00060     this->mutex_.Unlock();
00061   }
00062 }
00063 
00064 bool Notification::WaitForNotificationWithTimeout(
00065     absl::Duration timeout) const {
00066   bool notified = HasBeenNotifiedInternal(&this->notified_yet_);
00067   if (!notified) {
00068     notified = this->mutex_.LockWhenWithTimeout(
00069         Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout);
00070     this->mutex_.Unlock();
00071   }
00072   return notified;
00073 }
00074 
00075 bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const {
00076   bool notified = HasBeenNotifiedInternal(&this->notified_yet_);
00077   if (!notified) {
00078     notified = this->mutex_.LockWhenWithDeadline(
00079         Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline);
00080     this->mutex_.Unlock();
00081   }
00082   return notified;
00083 }
00084 
00085 }  // namespace absl


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15