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

#ifndef BASE_THREADING_SEQUENCE_BOUND_INTERNAL_H_
#define BASE_THREADING_SEQUENCE_BOUND_INTERNAL_H_

#include <memory>
#include <type_traits>
#include <utility>

#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"

namespace base::sequence_bound_internal {

struct CrossThreadTraits {
  template <typename Signature>
  using CrossThreadTask = OnceCallback<Signature>;

  template <typename Functor, typename... Args>
  static inline auto BindOnce(Functor&& functor, Args&&... args) {
    return ::base::BindOnce(std::forward<Functor>(functor),
                            std::forward<Args>(args)...);
  }

  template <typename T>
  static inline auto Unretained(T ptr) {
    return ::base::Unretained(ptr);
  }

  static inline bool PostTask(SequencedTaskRunner& task_runner,
                              const Location& location,
                              OnceClosure&& task) {
    return task_runner.PostTask(location, std::move(task));
  }

  static inline bool PostTaskAndReply(SequencedTaskRunner& task_runner,
                                      const Location& location,
                                      OnceClosure&& task,
                                      OnceClosure&& reply) {
    return task_runner.PostTaskAndReply(location, std::move(task),
                                        std::move(reply));
  }

  template <typename TaskReturnType, typename ReplyArgType>
  static inline bool PostTaskAndReplyWithResult(
      SequencedTaskRunner& task_runner,
      const Location& location,
      OnceCallback<TaskReturnType()>&& task,
      OnceCallback<void(ReplyArgType)>&& reply) {
    return task_runner.PostTaskAndReplyWithResult(location, std::move(task),
                                                  std::move(reply));
  }

  // Accept RepeatingCallback here since it's convertible to a OnceCallback.
  template <template <typename> class CallbackType>
  using EnableIfIsCrossThreadTask = EnableIfIsBaseCallback<CallbackType>;
};

template <typename T, typename CrossThreadTraits>
class Storage {
 public:
  using Ptr = T*;

  Ptr get() const { return ptr_; }

  // Marked NO_SANITIZE because cfi doesn't like casting uninitialized memory to
  // `T*`. However, this is safe here because:
  //
  // 1. The cast is well-defined (see https://eel.is/c++draft/basic.life#6) and
  // 2. The resulting pointer is only ever dereferenced on `task_runner`.
  //    By the time SequenceBound's constructor returns, the task to construct
  //    `T` will already be posted; thus, subsequent dereference of `ptr_` on
  //    `task_runner` are safe.
  template <typename... Args>
  NO_SANITIZE("cfi-unrelated-cast")
  void Construct(SequencedTaskRunner& task_runner, Args&&... args) {
    // TODO(https://crbug.com/1382549): Use universal forwarding and assert that
    // T is constructible from args for better error messages.
    DCHECK(!alloc_);
    DCHECK(!ptr_);

    // Allocate space for but do not construct an instance of `T`.
    // AlignedAlloc() requires alignment be a multiple of sizeof(void*).
    alloc_ = AlignedAlloc(
        sizeof(T), sizeof(void*) > alignof(T) ? sizeof(void*) : alignof(T));
    ptr_ = reinterpret_cast<Ptr>(alloc_.get());

    // Ensure that `ptr_` will be initialized.
    CrossThreadTraits::PostTask(
        task_runner, FROM_HERE,
        CrossThreadTraits::BindOnce(&InternalConstruct<Args...>,
                                    CrossThreadTraits::Unretained(ptr_),
                                    std::forward<Args>(args)...));
  }

  // Marked NO_SANITIZE since:
  // 1. SequenceBound can be moved before `ptr_` is constructed on its managing
  //    `SequencedTaskRunner` but
  // 2. Implicit conversions to non-virtual base classes are allowed before the
  //    lifetime of the object that `ptr_` points at has begun (see
  //    https://eel.is/c++draft/basic.life#6).
  template <typename U>
  NO_SANITIZE("cfi-unrelated-cast")
  void TakeFrom(Storage<U, CrossThreadTraits>&& other) {
    // Subtle: this must not use static_cast<>, since the lifetime of the
    // managed `T` may not have begun yet. However, the standard explicitly
    // still allows implicit conversion to a non-virtual base class.
    ptr_ = std::exchange(other.ptr_, nullptr);
    alloc_ = std::exchange(other.alloc_, nullptr);
  }

  void Destruct(SequencedTaskRunner& task_runner) {
    CrossThreadTraits::PostTask(
        task_runner, FROM_HERE,
        CrossThreadTraits::BindOnce(
            &InternalDestruct, CrossThreadTraits::Unretained(ptr_),
            CrossThreadTraits::Unretained(alloc_.get())));
    ptr_ = nullptr;
    alloc_ = nullptr;
  }

 private:
  // Needed to allow conversions from compatible `U`s.
  template <typename U, typename V>
  friend class Storage;

  // Helpers for constructing and destroying `T` on its managing
  // `SequencedTaskRunner`.
  template <typename... Args>
  static void InternalConstruct(T* ptr, std::decay_t<Args>&&... args) {
    new (ptr) T(std::move(args)...);
  }

  static void InternalDestruct(T* ptr, void* alloc) {
    ptr->~T();
    AlignedFree(alloc);
  }

  // Pointer to the managed `T`.
  Ptr ptr_ = nullptr;

  // Storage originally allocated by `AlignedAlloc()`. Maintained separately
  // from  `ptr_` since the original, unadjusted pointer needs to be passed to
  // `AlignedFree()`.
  raw_ptr<void, DanglingUntriaged> alloc_ = nullptr;
};

template <typename T, typename CrossThreadTraits>
struct Storage<std::unique_ptr<T>, CrossThreadTraits> {
 public:
  using Ptr = T*;

  Ptr get() const { return ptr_; }

  template <typename U>
  void Construct(SequencedTaskRunner& task_runner, std::unique_ptr<U> arg) {
    // TODO(https://crbug.com/1382549): Use universal forwarding and assert that
    // there is one arg that is a unique_ptr for better error messages.
    DCHECK(!ptr_);

    ptr_ = arg.release();
    // No additional storage needs to be allocated since `T` is already
    // constructed and lives on the heap.
  }

  template <typename U>
  void TakeFrom(Storage<std::unique_ptr<U>, CrossThreadTraits>&& other) {
    ptr_ = std::exchange(other.ptr_, nullptr);
  }

  void Destruct(SequencedTaskRunner& task_runner) {
    CrossThreadTraits::PostTask(
        task_runner, FROM_HERE,
        CrossThreadTraits::BindOnce(&InternalDestruct,
                                    CrossThreadTraits::Unretained(ptr_)));

    ptr_ = nullptr;
  }

 private:
  // Needed to allow conversions from compatible `U`s.
  template <typename U, typename V>
  friend class Storage;

  static void InternalDestruct(T* ptr) { delete ptr; }

  // Pointer to the heap-allocated `T`.
  Ptr ptr_ = nullptr;
};

}  // namespace base::sequence_bound_internal

#endif  // BASE_THREADING_SEQUENCE_BOUND_INTERNAL_H_
