#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_SUPPORT_THREADING_LATCH_H #define NUCLEX_SUPPORT_THREADING_LATCH_H #include "Nuclex/Support/Config.h" #include // for std::size_t #include // for std::chrono::microseconds namespace Nuclex { namespace Support { namespace Threading { // ------------------------------------------------------------------------------------------- // /// Blocks threads unless its counter has reached zero /// /// /// This is sometimes also called a reverse-counting semaphore. It will only /// let threads through if the counter is zero at the time of the Wait() call. /// /// /// This behavior is useful if you need to wait for a series of tasks to finish or /// resources used by several threads to become available. /// /// class NUCLEX_SUPPORT_TYPE Latch { /// Initializes a new countdown latch with the specified initial count /// /// Initial number of decrements needed for the countdown latch to become open /// public: NUCLEX_SUPPORT_API Latch(std::size_t initialCount = 0); /// Frees all resources owned by the countdown latch /// /// There should not be any threads waiting on the countdown latch when it is /// destroyed. The behavior for such threats is undefined, they may hang forever, // they may receive an exception or the entire process may be terminated. /// public: NUCLEX_SUPPORT_API ~Latch(); /// Increments the latch, blocking any threads from going through /// Number of times the latch will be incremented public: NUCLEX_SUPPORT_API void Post(std::size_t count = 1); /// Decrements the latch counter /// Number of times the latch will be decremented public: NUCLEX_SUPPORT_API void CountDown(std::size_t count = 1); /// Waits until the latch's count has reached zero /// /// This caues the calling thread to block if the latch's count hasn't already /// reached zero. If the thread is blocked, it will stay so until another /// thread calls on the latch. /// public: NUCLEX_SUPPORT_API void Wait() const; /// Waits until the latch's count has reached zero or a timeout occurs /// How long to wait for the latch before giving up /// /// True if the latch counter reached zero and let the thread through, /// false if the timeout elapsed and the latch counter was still greater than zero. /// /// /// This causes the calling thread to block if the latch counter didn't already /// reach zero. If the thread is blocked, it will stay so until another /// thread calls on the latch or until the specified /// patience time has elapsed. /// public: NUCLEX_SUPPORT_API bool WaitFor( const std::chrono::microseconds &patience ) const; //public: void WaitUntil(const std::chrono::time_point< &patience); /// Structure to hold platform dependent process and file handles private: struct PlatformDependentImplementationData; /// Accesses the platform dependent implementation data container /// A reference to the platform dependent implementation data private: const PlatformDependentImplementationData &getImplementationData() const; /// Accesses the platform dependent implementation data container /// A reference to the platform dependent implementation data private: PlatformDependentImplementationData &getImplementationData(); #if defined(NUCLEX_SUPPORT_LINUX) || defined(NUCLEX_SUPPORT_WINDOWS) alignas(8) unsigned char implementationDataBuffer[sizeof(std::size_t) * 2]; #else // Posix unsigned char implementationDataBuffer[96]; #endif }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Support::Threading #endif // NUCLEX_SUPPORT_THREADING_LATCH_H