blob: b88be468ee27c7f9d515166d04ee583972ebe423 [file] [log] [blame]
// 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 decrement.
///
[[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_