// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ============================================================================
// This is an accompanying example code for writing thread safe code in C++.
// Head over there for the full walk-through:
// https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/thread-safe-async
// ============================================================================

#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/sequence_checker.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/channel.h>

#include <gtest/gtest.h>

namespace {

// [START synchronization_checker]
TEST(Async, SynchronizationCheckerExample) {
  // |ChannelReader| lets one asynchronously read from a Zircon channel.
  //
  // ## Thread safety
  //
  // Instances must be used from a synchronized async dispatcher. See
  // https://fuchsia.dev/fuchsia-src/development/languages/c-cpp/thread-safe-async#synchronized-dispatcher
  class ChannelReader {
   public:
    ChannelReader(async_dispatcher_t* dispatcher, zx::channel channel)
        : dispatcher_(dispatcher),
          checker_(dispatcher),
          channel_(std::move(channel)),
          wait_(channel_.get(), ZX_CHANNEL_READABLE) {}

    ~ChannelReader() {
      // |lock| explicitly checks that the dispatcher is not calling callbacks
      // that use this |ChannelReader| instance in the meantime.
      checker_.lock();
    }

    // Asynchronously wait for the channel to become readable, then read the
    // data into a member variable.
    void AsyncRead() {
      // This guard checks that the |AsyncRead| method is called from a task
      // running on a synchronized dispatcher.
      std::lock_guard guard(checker_);

      data_.clear();

      zx_status_t status = wait_.Begin(
          // The dispatcher that will perform the waiting.
          dispatcher_,

          // The async dispatcher will call this callback when the channel is
          // ready to be read from. Because this callback captures `this`, we
          // must ensure the callback does not race with destroying the
          // |ChannelReader| instance. This is accomplished by calling
          // `checker_.lock()` in the |ChannelReader| destructor.
          [this](async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                 const zx_packet_signal_t* signal) {
            if (status != ZX_OK) {
              return;
            }
            std::lock_guard guard(checker_);

            uint32_t actual;
            data_.resize(ZX_CHANNEL_MAX_MSG_BYTES);
            status = channel_.read(0, data_.data(), nullptr,
                                   static_cast<uint32_t>(data_.capacity()), 0, &actual, nullptr);
            if (status != ZX_OK) {
              data_.clear();
              return;
            }
            data_.resize(actual);
          });
      ZX_ASSERT(status == ZX_OK);
    }

    std::vector<uint8_t> data() const {
      // Here we also verify synchronization, because we want to avoid race
      // conditions such as the user calling |AsyncRead| which clears the
      // data and calling |data| to get the data at the same time.
      std::lock_guard guard(checker_);

      return data_;
    }

   private:
    async_dispatcher_t* dispatcher_;
    async::synchronization_checker checker_;
    zx::channel channel_;
    std::vector<uint8_t> data_ __TA_GUARDED(checker_);
    async::WaitOnce wait_;
  };

  zx::channel c1, c2;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &c1, &c2));

  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  ChannelReader reader{loop.dispatcher(), std::move(c1)};

  ASSERT_EQ(reader.data(), std::vector<uint8_t>{});

  const std::vector<uint8_t> kData{1, 2, 3};
  ASSERT_EQ(ZX_OK, c2.write(0, kData.data(), static_cast<uint32_t>(kData.size()), nullptr, 0));

  // Using |reader| must be synchronized with dispatching asynchronous operations.
  // Here, they are synchronized because we perform these one after the other
  // from a single thread.
  reader.AsyncRead();
  loop.RunUntilIdle();

  ASSERT_EQ(reader.data(), kData);

  // The following is disallowed, and would lead to a panic.
  // If the dispatcher is running from a different thread, then we cannot
  // ensure that |reader| is not used in the meantime.
  //
  // std::thread([&] { loop.RunUntilIdle(); }).join();
}
// [END synchronization_checker]

}  // namespace
