Repository: carbon-language/carbon-lang
File: common/latch.h (C/C++)

Code before:
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CARBON_COMMON_LATCH_H_
#define CARBON_COMMON_LATCH_H_

#include <atomic>

#include "llvm/ADT/FunctionExtras.h"

namespace Carbon {

// A synchronization primitive similar to `std::latch` to coordinate starting
// some action once all of a set of other actions complete.
//
// Users initialize the latch (with `Init), and receive a handle RAII object.
// This handle can be copied, and the latch is satisfied when the last copy of
// the handle returned by `Init` is destroyed.
//
// The latch synchronizes between every destruction of a handle and the
// destruction of the last handle, allowing code that runs after the latch is
// satisfied to access everything written by threads that destroy a handle. For
// more details of the synchronization mechanics, see the comments on `Inc` and
// `Dec` that implement this logic.
//
// This type also supports holding a closure to run when satisfied to simplify
// patterns where that body of code is easier to express at the start of work
// being synchronized instead of as each work item completes.
//
// The initialization API is separate from the constructor both for convenience
// and to enable it to provide the initial handle. This makes it easy to build
// constructively correct code where each work unit holds a handle until
// finished, including the initializer of the latch, often using by-value
// captures in a lambda that does the work.
class Latch {
 public:
  class Handle;

  Latch() = default;
  Latch(const Latch&) = delete;
  Latch(Latch&&) = delete;

  // Initialize a latch and get the initial handle to it.
  //
  // When the last copy of the returned handle is destroyed, the latch will be
  // satisfied.
  //

Review comment (suggestion):
```suggestion
// satisfied to access everything written by any thread that destroyed a handle. For
```

Code after:
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CARBON_COMMON_LATCH_H_
#define CARBON_COMMON_LATCH_H_

#include <atomic>

#include "llvm/ADT/FunctionExtras.h"

namespace Carbon {

// A synchronization primitive similar to `std::latch` to coordinate starting
// some action once all of a set of other actions complete.
//
// Users initialize the latch (with `Init`), and receive a handle RAII object.
// This handle can be copied, and the latch is satisfied when the last copy of
// the handle returned by `Init` is destroyed.
//
// The latch synchronizes between every destruction of a handle and the
// destruction of the last handle, allowing code that runs after the latch is
// satisfied to access everything written by any thread that destroyed a handle.
// For more details of the synchronization mechanics, see the comments on `Inc`
// and `Dec` that implement this logic.
//
// This type also supports holding a closure to run when satisfied to simplify
// patterns where that body of code is easier to express at the start of work
// being synchronized instead of as each work item completes.
//
// The initialization API is separate from the constructor both for convenience
// and to enable it to provide the initial handle. This makes it easy to build
// constructively correct code where each work unit holds a handle until
// finished, including the initializer of the latch, often using by-value
// captures in a lambda that does the work.
class Latch {
 public:
  class Handle;

  Latch() = default;
  Latch(const Latch&) = delete;
  Latch(Latch&&) = delete;

  // Initialize a latch and get the initial handle to it.
  //
  // When the last copy of the returned handle is destroyed, the latch will be
  // satisfied.
  //