// Copyright 2018 The Chromium 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 BASE_THREADING_SEQUENCE_BOUND_H_
#define BASE_THREADING_SEQUENCE_BOUND_H_

#include <new>
#include <type_traits>

#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"

namespace base {

// SequenceBound facilitates owning objects that live on a specified sequence,
// which is potentially different than the owner's sequence.  It encapsulates
// the work of posting tasks to the specified sequence to construct T, call
// methods on T, and destroy T.
//
// It does not provide explicit access to the underlying object directly, to
// prevent accidentally using it from the wrong sequence.
//
// Like std::unique_ptr<T>, a SequenceBound<T> may be moved between owners,
// and posted across threads.  It may also be up-casted (only), to permit
// SequenceBound to be used with interfaces.
//
// Basic usage looks like this:
//
//   // Some class that lives on |main_task_runner|.
//   class MyClass {
//    public:
//     explicit MyClass(const char* widget_title) {}
//     virtual ~MyClass() { ... }
//     virtual void DoSomething(int arg) { ... }
//   };
//
//   // On any thread...
//   scoped_refptr<SequencedTaskRunner> main_task_runner = ...;
//   auto widget = SequenceBound<MyClass>(main_task_runner, "My Title");
//   widget.Post(&MyObject::DoSomething, 1234);
//
// Note that |widget| is constructed asynchronously on |main_task_runner|,
// but calling Post() immediately is safe, since the actual call is posted
// to |main_task_runner| as well.
//
// |widget| will be deleted on |main_task_runner| asynchronously when it goes
// out of scope, or when Reset() is called.
//
// Here is a more complicated example that shows injection and upcasting:
//
//   // Some unrelated class that uses a |MyClass| to do something.
//   class SomeConsumer {
//    public:
//    // Note that ownership of |widget| is given to us!
//    explicit SomeConsumer(SequenceBound<MyClass> widget)
//        : widget_(std::move(widget)) { ... }
//
//    ~SomeConsumer() {
//      // |widget_| will be destroyed on the associated task runner.
//    }
//
//     SequenceBound<MyClass> widget_;
//   };
//
//   // Implementation of MyClass.
//   class MyDerivedClass : public MyClass { ... };
//
//   auto widget =
//     SequenceBound<MyDerivedClass>(main_task_runner, ctor args);
//   auto c = new SomeConsumer(std::move(widget));  // upcasts to MyClass

namespace internal {

// If we can't cast |Base*| into |Derived*|, then it's a virtual base if and
// only if |Base| is actually a base class of |Derived|.  Otherwise (including
// unrelated types), it isn't.  We default to Derived* so that the
// specialization below will apply when the cast to |Derived*| is valid.
template <typename Base, typename Derived, typename = Derived*>
struct is_virtual_base_of : public std::is_base_of<Base, Derived> {};

// If we can cast |Base*| into |Derived*|, then it's definitely not a virtual
// base.  When this happens, we'll match the default third template argument.
template <typename Base, typename Derived>
struct is_virtual_base_of<Base,
                          Derived,
                          decltype(static_cast<Derived*>(
                              static_cast<Base*>(nullptr)))> : std::false_type {
};

}  // namespace internal

template <typename T>
class SequenceBound {
 public:
  // Allow explicit null.
  SequenceBound() = default;

  // Construct a new instance of |T| that will be accessed only on
  // |task_runner|.  One may post calls to it immediately upon return.
  // This is marked as NO_SANITIZE because cfi doesn't like that we're casting
  // uninitialized memory to a |T*|.  However, it's safe since (a) the cast is
  // defined (see http://eel.is/c++draft/basic.life#6 for details), and (b) we
  // don't use the resulting pointer in any way that requries it to be
  // constructed, except by posting such a access to |impl_task_runner_| after
  // posting construction there as well.
  template <typename... Args>
  NO_SANITIZE("cfi-unrelated-cast")
  SequenceBound(scoped_refptr<base::SequencedTaskRunner> task_runner,
                Args&&... args)
      : impl_task_runner_(std::move(task_runner)) {
    // Allocate space for but do not construct an instance of |T|.
    storage_ = AlignedAlloc(sizeof(T), alignof(T));
    t_ = reinterpret_cast<T*>(storage_);

    // Post construction to the impl thread.
    impl_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&ConstructOwnerRecord<Args...>, base::Unretained(t_),
                       std::forward<Args>(args)...));
  }

  ~SequenceBound() { Reset(); }

  // Move construction from the same type can just take the pointer without
  // adjusting anything.  This is required in addition to the move conversion
  // constructor below.
  SequenceBound(SequenceBound&& other) { MoveRecordFrom(other); }

  // Move construction is supported from any type that's compatible with |T|.
  // This case handles |From| != |T|, so we must adjust the pointer offset.
  template <typename From>
  SequenceBound(SequenceBound<From>&& other) {
    MoveRecordFrom(other);
  }

  SequenceBound& operator=(SequenceBound&& other) {
    // Clean up any object we currently own.
    Reset();
    MoveRecordFrom(other);
    return *this;
  }

  template <typename From>
  SequenceBound<T>& operator=(SequenceBound<From>&& other) {
    // Clean up any object that we currently own.
    Reset();
    MoveRecordFrom(other);
    return *this;
  }

  // Move everything from |other|, doing pointer adjustment as needed.
  // This method is marked as NO_SANITIZE since (a) it might run before the
  // posted ctor runs on |impl_task_runner_|, and (b) implicit conversions to
  // non-virtual base classes are allowed before construction by the standard.
  // See http://eel.is/c++draft/basic.life#6 for more information.
  template <typename From>
  void NO_SANITIZE("cfi-unrelated-cast") MoveRecordFrom(From&& other) {
    // |other| might be is_null(), but that's okay.
    impl_task_runner_ = std::move(other.impl_task_runner_);

    // Note that static_cast<> isn't, in general, safe, since |other| might not
    // be constructed yet.  Implicit conversion is supported, as long as it
    // doesn't convert to a virtual base.  Of course, it allows only upcasts.
    t_ = other.t_;

    // The original storage is kept unmodified, so we can free it later.
    storage_ = other.storage_;

    other.storage_ = nullptr;
    other.t_ = nullptr;
  }

  // Post a call to |method| to |impl_task_runner_|.
  template <typename... MethodArgs, typename... Args>
  void Post(const base::Location& from_here,
            void (T::*method)(MethodArgs...),
            Args&&... args) const {
    impl_task_runner_->PostTask(from_here,
                                base::BindOnce(method, base::Unretained(t_),
                                               std::forward<Args>(args)...));
  }

  // TODO(liberato): Add PostOrCall(), to support cases where synchronous calls
  // are okay if it's the same task runner.

  // TODO(liberato): Add PostAndReply()

  // TODO(liberato): Allow creation of callbacks that bind to a weak pointer,
  // and thread-hop to |impl_task_runner_| if needed.

  // Post destruction of any object we own, and return to the null state.
  void Reset() {
    if (is_null())
      return;

    // Destruct the object on the impl thread.
    impl_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&DeleteOwnerRecord, base::Unretained(t_),
                                  base::Unretained(storage_)));

    impl_task_runner_ = nullptr;
    t_ = nullptr;
    storage_ = nullptr;
  }

  // Return whether we own anything.  Note that this does not guarantee that any
  // previously owned object has been destroyed.  In particular, it will return
  // true immediately after a call to Reset(), though the underlying object
  // might still be pending destruction on the impl thread.
  bool is_null() const { return !t_; }

  // True if and only if we have an object, with the same caveats as is_null().
  explicit operator bool() const { return !is_null(); }

 private:
  // Pointer to the object,  Pointer may be modified on the owning thread.
  T* t_ = nullptr;

  // Original allocated storage for the object.
  void* storage_ = nullptr;

  // The task runner on which all access to |t_| should happen.
  scoped_refptr<base::SequencedTaskRunner> impl_task_runner_;

  // For move conversion.
  template <typename U>
  friend class SequenceBound;

  // Run on impl thread to construct |t|'s storage.
  template <typename... Args>
  static void ConstructOwnerRecord(T* t, Args&&... args) {
    new (t) T(std::forward<Args>(args)...);
  }

  // Destruct the object associated with |t|, and delete |storage|.
  static void DeleteOwnerRecord(T* t, void* storage) {
    t->~T();
    AlignedFree(storage);
  }

  // To preserve ownership semantics, we disallow copy construction / copy
  // assignment.  Move construction / assignment is fine.
  DISALLOW_COPY_AND_ASSIGN(SequenceBound);
};

}  // namespace base

#endif  // BASE_THREADING_SEQUENCE_BOUND_H_
