├── LICENSE ├── README.md ├── countdownlatch.cpp ├── countdownlatch.hpp └── example_run.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Nipun Talukdar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CountdownLatch for C++ multi-threaded programming 2 | ================================================ 3 | 4 | **CountdownLatch in C++** 5 | 6 | ----------------------- 7 | countdownlatch is a C++ library providing similar functionalities as availble with standard Java 8 | CountdownLatch class. It's main usage is: it allows one or more threads to wait until a set of 9 | operations being performed on other threads completes. 10 | 11 | 12 | **Below is an example regarding how to use the library** 13 | 14 | --- 15 | 16 | ```c++ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void fun(clatch::countdownlatch *cl) { 24 | cl->await(); 25 | std::cout << "Wait is over " << std::endl; 26 | } 27 | 28 | int main() { 29 | auto cl = new clatch::countdownlatch(10); 30 | int i = 0; 31 | std::vector ts; 32 | while (i++ < 2) { 33 | std::thread *t = new std::thread(fun, cl); 34 | ts.push_back(t); 35 | } 36 | 37 | i = 0; 38 | while (i++ < 10) { 39 | sleep(1); 40 | cl->count_down(); 41 | } 42 | i = 0; 43 | while (i < 2) { 44 | ts[i++]->join(); 45 | } 46 | i = 0; 47 | while (i < 2) { 48 | delete ts[i++]; 49 | } 50 | delete cl; 51 | return 0; 52 | } 53 | 54 | ``` 55 | -------------------------------------------------------------------------------- /countdownlatch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | clatch::countdownlatch::countdownlatch(uint32_t count) { 5 | this->count = count; 6 | } 7 | 8 | void clatch::countdownlatch::await(uint64_t nanosecs) { 9 | std::unique_lock lck(lock); 10 | if (0 == count){ 11 | return; 12 | } 13 | if (nanosecs > 0) { 14 | cv.wait_for(lck, std::chrono::nanoseconds(nanosecs)); 15 | } else { 16 | cv.wait(lck); 17 | } 18 | } 19 | 20 | uint32_t clatch::countdownlatch::get_count() { 21 | std::unique_lock lck(lock); 22 | return count; 23 | } 24 | 25 | void clatch::countdownlatch::count_down() { 26 | std::unique_lock lck(lock); 27 | if (0 == count) { 28 | return; 29 | } 30 | --count; 31 | if (0 == count) { 32 | cv.notify_all(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /countdownlatch.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __COUNTDOWNLATCH_NIPUN__ 2 | #define __COUNTDOWNLATCH_NIPUN__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | namespace clatch 11 | { 12 | class countdownlatch { 13 | public: 14 | /*! Constructor 15 | \param count, the value the countdownlatch object should be initialized with 16 | */ 17 | countdownlatch(uint32_t count); 18 | 19 | 20 | /*! 21 | await causes the caller to wait until the latch is counted down to zero, 22 | if wait time nanosecs is not zero, then maximum wait is for nanosec nanoseconds 23 | \param nanosecs is waittime in nanoseconds, by default it is zero which specifies 24 | indefinite wait 25 | */ 26 | void await(uint64_t nanosecs=0); 27 | 28 | /*! 29 | Countdown decrements the count of the latch, signalling all waiting thread if the 30 | count reaches zero. 31 | */ 32 | void count_down(); 33 | 34 | /*! 35 | get_count returns the current count 36 | */ 37 | uint32_t get_count(); 38 | 39 | private: 40 | std::condition_variable cv; 41 | std::mutex lock; 42 | uint32_t count; 43 | 44 | // deleted constructors/assignmenet operators 45 | countdownlatch() = delete; 46 | countdownlatch(const countdownlatch& other) = delete; 47 | countdownlatch& operator=(const countdownlatch& opther) = delete; 48 | }; 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /example_run.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void fun(clatch::countdownlatch *cl) { 8 | cl->await(); 9 | std::cout << "Wait is over " << std::endl; 10 | } 11 | 12 | int main() { 13 | auto cl = new clatch::countdownlatch(10); 14 | int i = 0; 15 | std::vector ts; 16 | while (i++ < 2) { 17 | std::thread *t = new std::thread(fun, cl); 18 | ts.push_back(t); 19 | } 20 | 21 | i = 0; 22 | while (i++ < 10) { 23 | sleep(1); 24 | cl->count_down(); 25 | } 26 | i = 0; 27 | while (i < 2) { 28 | ts[i++]->join(); 29 | } 30 | i = 0; 31 | while (i < 2) { 32 | delete ts[i++]; 33 | } 34 | delete cl; 35 | return 0; 36 | } 37 | --------------------------------------------------------------------------------