blocking_counter.h
Go to the documentation of this file.
00001 //
00002 // Copyright 2017 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 //
00016 // -----------------------------------------------------------------------------
00017 // blocking_counter.h
00018 // -----------------------------------------------------------------------------
00019 
00020 #ifndef ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_
00021 #define ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_
00022 
00023 #include "absl/base/thread_annotations.h"
00024 #include "absl/synchronization/mutex.h"
00025 
00026 namespace absl {
00027 
00028 // BlockingCounter
00029 //
00030 // This class allows a thread to block for a pre-specified number of actions.
00031 // `BlockingCounter` maintains a single non-negative abstract integer "count"
00032 // with an initial value `initial_count`. A thread can then call `Wait()` on
00033 // this blocking counter to block until the specified number of events occur;
00034 // worker threads then call 'DecrementCount()` on the counter upon completion of
00035 // their work. Once the counter's internal "count" reaches zero, the blocked
00036 // thread unblocks.
00037 //
00038 // A `BlockingCounter` requires the following:
00039 //     - its `initial_count` is non-negative.
00040 //     - the number of calls to `DecrementCount()` on it is at most
00041 //       `initial_count`.
00042 //     - `Wait()` is called at most once on it.
00043 //
00044 // Given the above requirements, a `BlockingCounter` provides the following
00045 // guarantees:
00046 //     - Once its internal "count" reaches zero, no legal action on the object
00047 //       can further change the value of "count".
00048 //     - When `Wait()` returns, it is legal to destroy the `BlockingCounter`.
00049 //     - When `Wait()` returns, the number of calls to `DecrementCount()` on
00050 //       this blocking counter exactly equals `initial_count`.
00051 //
00052 // Example:
00053 //     BlockingCounter bcount(N);         // there are N items of work
00054 //     ... Allow worker threads to start.
00055 //     ... On completing each work item, workers do:
00056 //     ... bcount.DecrementCount();      // an item of work has been completed
00057 //
00058 //     bcount.Wait();                    // wait for all work to be complete
00059 //
00060 class BlockingCounter {
00061  public:
00062   explicit BlockingCounter(int initial_count)
00063       : count_(initial_count), num_waiting_(0) {}
00064 
00065   BlockingCounter(const BlockingCounter&) = delete;
00066   BlockingCounter& operator=(const BlockingCounter&) = delete;
00067 
00068   // BlockingCounter::DecrementCount()
00069   //
00070   // Decrements the counter's "count" by one, and return "count == 0". This
00071   // function requires that "count != 0" when it is called.
00072   //
00073   // Memory ordering: For any threads X and Y, any action taken by X
00074   // before it calls `DecrementCount()` is visible to thread Y after
00075   // Y's call to `DecrementCount()`, provided Y's call returns `true`.
00076   bool DecrementCount();
00077 
00078   // BlockingCounter::Wait()
00079   //
00080   // Blocks until the counter reaches zero. This function may be called at most
00081   // once. On return, `DecrementCount()` will have been called "initial_count"
00082   // times and the blocking counter may be destroyed.
00083   //
00084   // Memory ordering: For any threads X and Y, any action taken by X
00085   // before X calls `DecrementCount()` is visible to Y after Y returns
00086   // from `Wait()`.
00087   void Wait();
00088 
00089  private:
00090   Mutex lock_;
00091   int count_ GUARDED_BY(lock_);
00092   int num_waiting_ GUARDED_BY(lock_);
00093 };
00094 
00095 }  // namespace absl
00096 
00097 #endif  // ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_


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