| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ | |
| #define FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ | |
| #include <memory> | |
| #include "flutter/fml/compiler_specific.h" | |
| #include "flutter/fml/macros.h" | |
| namespace fml { | |
| class PlatformSemaphore; | |
| //------------------------------------------------------------------------------ | |
| /// @brief A traditional counting semaphore. `Wait`s decrement the counter | |
| /// and `Signal` increments it. | |
| /// | |
| /// This is a cross-platform replacement for std::counting_semaphore | |
| /// which is only available since C++20. Once Flutter migrates past | |
| /// that point, this class should become obsolete and must be | |
| /// replaced. | |
| /// | |
| class Semaphore { | |
| public: | |
| //---------------------------------------------------------------------------- | |
| /// @brief Initializes the counting semaphore to a specified start count. | |
| /// | |
| /// @warning Callers must check if the handle could be successfully created | |
| /// by calling the `IsValid` method. `Wait`s on an invalid | |
| /// semaphore will always fail and signals will fail silently. | |
| /// | |
| /// @param[in] count The starting count of the counting semaphore. | |
| /// | |
| explicit Semaphore(uint32_t count); | |
| //---------------------------------------------------------------------------- | |
| /// @brief Destroy the counting semaphore. | |
| /// | |
| ~Semaphore(); | |
| //---------------------------------------------------------------------------- | |
| /// @brief Check if the underlying semaphore handle could be created. | |
| /// Failure modes are platform specific and may occur due to issue | |
| /// like handle exhaustion. All `Wait`s on invalid semaphore | |
| /// handles will fail and `Signal` calls will be ignored. | |
| /// | |
| /// @return True if valid, False otherwise. | |
| /// | |
| bool IsValid() const; | |
| //---------------------------------------------------------------------------- | |
| /// @brief Decrements the count and waits indefinitely if the value is | |
| /// less than zero for a `Signal`. | |
| /// | |
| /// @return If the `Wait` call was successful. See `IsValid` for failure. | |
| /// | |
| [[nodiscard]] bool Wait(); | |
| //---------------------------------------------------------------------------- | |
| /// @brief Decrement the counts if it is greater than zero. Returns false | |
| /// if the counter is already at zero. | |
| /// | |
| /// @warning False is also returned if the semaphore handle is invalid. | |
| /// Which makes doing the validity check before this call doubly | |
| /// important. | |
| /// | |
| /// @return If the count could be decremented. | |
| /// | |
| [[nodiscard]] bool TryWait(); | |
| //---------------------------------------------------------------------------- | |
| /// @brief Increment the count by one. Any pending `Wait`s will be | |
| /// resolved at this point. | |
| /// | |
| void Signal(); | |
| private: | |
| std::unique_ptr<PlatformSemaphore> impl_; | |
| FML_DISALLOW_COPY_AND_ASSIGN(Semaphore); | |
| }; | |
| } // namespace fml | |
| #endif // FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ |