// Copyright 2016 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 file provides weak pointers and weak pointer factories that work like
// Chromium's |base::WeakPtr<T>| and |base::WeakPtrFactory<T>|. Note that we do
// not provide anything analogous to |base::SupportsWeakPtr<T>|.

#ifndef SRC_LIB_FXL_MEMORY_WEAK_PTR_H_
#define SRC_LIB_FXL_MEMORY_WEAK_PTR_H_

#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>

#include <cstddef>
#include <utility>

#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr_internal.h"

namespace fxl {

// Forward declaration, so |WeakPtr<T>| can friend it.
template <typename T>
class WeakPtrFactory;

// Class for "weak pointers" that can be invalidated. Valid weak pointers can
// only originate from a |WeakPtrFactory| (see below), though weak pointers are
// copyable and movable.
//
// Weak pointers are not in general thread-safe. They may only be *used* on a
// single thread, namely the same thread as the "originating" |WeakPtrFactory|
// (which can invalidate the weak pointers that it generates).
//
// However, weak pointers may be passed to other threads, reset on other
// threads, or destroyed on other threads. They may also be reassigned on other
// threads (in which case they should then only be used on the thread
// corresponding to the new "originating" |WeakPtrFactory|).
template <typename T>
class WeakPtr {
 public:
  WeakPtr() : ptr_(nullptr) {}
  WeakPtr(std::nullptr_t) : WeakPtr() {}

  // Copy constructor.
  WeakPtr(const WeakPtr<T>& r) = default;

  template <typename U>
  WeakPtr(const WeakPtr<U>& r) : ptr_(r.ptr_), flag_(r.flag_) {}

  // Move constructor.
  WeakPtr(WeakPtr<T>&& r) = default;

  template <typename U>
  WeakPtr(WeakPtr<U>&& r) : ptr_(std::exchange(r.ptr_, nullptr)), flag_(std::move(r.flag_)) {}

  ~WeakPtr() = default;

  // The following methods are thread-friendly, in the sense that they may be
  // called subject to additional synchronization.

  // Copy assignment.
  WeakPtr<T>& operator=(const WeakPtr<T>& r) = default;

  // Move assignment.
  WeakPtr<T>& operator=(WeakPtr<T>&& r) = default;

  void reset() { flag_ = nullptr; }

  // The following methods should only be called on the same thread as the
  // "originating" |WeakPtrFactory|.

  explicit operator bool() const { return flag_ && flag_->is_valid(); }

  T* get() const { return *this ? ptr_ : nullptr; }

  T& operator*() const {
    FX_DCHECK(*this);
    return *get();
  }

  T* operator->() const {
    FX_DCHECK(*this);
    return get();
  }

 private:
  template <typename U>
  friend class WeakPtr;

  friend class WeakPtrFactory<T>;

  explicit WeakPtr(T* ptr, RefPtr<internal::WeakPtrFlag>&& flag)
      : ptr_(ptr), flag_(std::move(flag)) {}

  T* ptr_;
  RefPtr<internal::WeakPtrFlag> flag_;

  // Copy/move construction/assignment supported.
};

// Class that produces (valid) |WeakPtr<T>|s. Typically, this is used as a
// member variable of |T| (preferably the last one -- see below), and |T|'s
// methods control how weak pointers to it are vended. This class is not
// thread-safe, and should only be used on a single thread.
//
// Example:
//
//  class Controller {
//   public:
//    Controller() : ..., weak_factory_(this) {}
//    ...
//
//    void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
//    void WorkComplete(const Result& result) { ... }
//
//   private:
//    ...
//
//    // Member variables should appear before the |WeakPtrFactory|, to ensure
//    // that any |WeakPtr|s to |Controller| are invalidated before its member
//    // variables' destructors are executed.
//    WeakPtrFactory<Controller> weak_factory_;
//  };
//
//  class Worker {
//   public:
//    static void StartNew(const WeakPtr<Controller>& controller) {
//      Worker* worker = new Worker(controller);
//      // Kick off asynchronous processing....
//    }
//
//   private:
//    Worker(const WeakPtr<Controller>& controller) : controller_(controller) {}
//
//    void DidCompleteAsynchronousProcessing(const Result& result) {
//      if (controller_)
//        controller_->WorkComplete(result);
//    }
//
//    WeakPtr<Controller> controller_;
//  };
template <typename T>
class WeakPtrFactory {
 public:
  explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { FX_DCHECK(ptr_); }
  ~WeakPtrFactory() {
    InvalidateWeakPtrs();
    FX_DCHECK(*reinterpret_cast<uintptr_t volatile*>(const_cast<T**>(&ptr_)) = kPoisonedPointer);
  }

  // Gets a new weak pointer, which will be valid until either
  // |InvalidateWeakPtrs()| is called or this object is destroyed.
  WeakPtr<T> GetWeakPtr() {
    FX_DCHECK(reinterpret_cast<uintptr_t>(ptr_) != kPoisonedPointer);
    if (!flag_)
      flag_ = MakeRefCounted<internal::WeakPtrFlag>();
    return WeakPtr<T>(ptr_, flag_.Clone());
  }

  // Call this method to invalidate all existing weak pointers. (Note that
  // additional weak pointers can be produced even after this is called.)
  void InvalidateWeakPtrs() {
    if (!flag_)
      return;
    flag_->Invalidate();
    flag_ = nullptr;
  }

  // Call this method to determine if any weak pointers exist. (Note that a
  // "false" result is definitive, but a "true" result may not be if weak
  // pointers are held/reset/destroyed/reassigned on other threads.)
  bool HasWeakPtrs() const { return flag_ && !flag_->HasOneRef(); }

 private:
  // Value to poison |ptr_| with in debug mode to ensure that weak pointer are
  // not generated once this class has been destroyed.
  // Value must be different from 0, and invalid as a real pointer address.
  static constexpr uintptr_t kPoisonedPointer = 1;
  // Note: See weak_ptr_internal.h for an explanation of why we store the
  // pointer here, instead of in the "flag".
  T* const ptr_;
  RefPtr<internal::WeakPtrFlag> flag_;

  FXL_DISALLOW_COPY_AND_ASSIGN(WeakPtrFactory);
};

}  // namespace fxl

#endif  // SRC_LIB_FXL_MEMORY_WEAK_PTR_H_
