// 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_TASK_SCHEDULER_TRACKED_REF_H_
#define BASE_TASK_SCHEDULER_TRACKED_REF_H_

#include <memory>

#include "base/atomic_ref_count.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/waitable_event.h"

namespace base {
namespace internal {

// TrackedRefs are effectively a ref-counting scheme for objects that have a
// single owner.
//
// Deletion is still controlled by the single owner but ~T() itself will block
// until all the TrackedRefs handed by its TrackedRefFactory have been released
// (by ~TrackedRef<T>()).
//
// Just like WeakPtrFactory: TrackedRefFactory<T> should be the last member of T
// to ensure ~TrackedRefFactory<T>() runs first in ~T().
//
// The owner of a T should hence be certain that the last TrackedRefs to T are
// already gone or on their way out before destroying it or ~T() will hang
// (indicating a bug in the tear down logic -- proper refcounting on the other
// hand would result in a leak).
//
// TrackedRefFactory only makes sense to use on types that are always leaked in
// production but need to be torn down in tests (blocking destruction is
// impractical in production -- ref. ScopedAllowBaseSyncPrimitivesForTesting
// below).
//
// Why would we ever need such a thing? In task_scheduler there is a clear
// ownership hierarchy with mostly single owners and little refcounting. In
// production nothing is ever torn down so this isn't a problem. In tests
// however we must JoinForTesting(). At that point, all the raw back T* refs
// used by the worker threads are problematic because they can result in use-
// after-frees if a worker outlives the deletion of its corresponding
// TaskScheduler/TaskTracker/SchedulerWorkerPool/etc.
//
// JoinForTesting() isn't so hard when all workers are managed. But with cleanup
// semantics (reclaiming a worker who's been idle for too long) it becomes
// tricky because workers can go unaccounted for before they exit their main
// (https://crbug.com/827615).
//
// For that reason and to clearly document the ownership model, task_scheduler
// uses TrackedRefs.
//
// On top of being a clearer ownership model than proper refcounting, a hang in
// tear down in a test with out-of-order tear down logic is much preferred to
// letting its worker thread and associated constructs outlive the test
// (potentially resulting in flakes in unrelated tests running later in the same
// process).
//
// Note: While there's nothing task_scheduler specific about TrackedRefs it
// requires an ownership model where all the TrackedRefs are released on other
// threads in sync with ~T(). This isn't a typical use case beyond shutting down
// TaskScheduler in tests and as such this is kept internal here for now.

template <class T>
class TrackedRefFactory;

// TrackedRef<T> can be used like a T*.
template <class T>
class TrackedRef {
 public:
  // Moveable and copyable.
  TrackedRef(TrackedRef<T>&& other)
      : ptr_(other.ptr_), factory_(other.factory_) {
    // Null out |other_|'s factory so its destructor doesn't decrement
    // |live_tracked_refs_|.
    other.factory_ = nullptr;
  }
  TrackedRef(const TrackedRef<T>& other)
      : ptr_(other.ptr_), factory_(other.factory_) {
    factory_->live_tracked_refs_.Increment();
  }

  // Intentionally not assignable for now because it makes the logic slightly
  // convoluted and it's not a use case that makes sense for the types using
  // this at the moment.
  TrackedRef& operator=(TrackedRef<T>&& other) = delete;
  TrackedRef& operator=(const TrackedRef<T>& other) = delete;

  ~TrackedRef() {
    if (factory_ && !factory_->live_tracked_refs_.Decrement()) {
      DCHECK(factory_->ready_to_destroy_);
      DCHECK(!factory_->ready_to_destroy_->IsSignaled());
      factory_->ready_to_destroy_->Signal();
    }
  }

  T& operator*() const { return *ptr_; }

  T* operator->() const { return ptr_; }

  explicit operator bool() const { return ptr_ != nullptr; }

 private:
  friend class TrackedRefFactory<T>;

  TrackedRef(T* ptr, TrackedRefFactory<T>* factory)
      : ptr_(ptr), factory_(factory) {
    factory_->live_tracked_refs_.Increment();
  }

  T* ptr_;
  TrackedRefFactory<T>* factory_;
};

// TrackedRefFactory<T> should be the last member of T.
template <class T>
class TrackedRefFactory {
 public:
  TrackedRefFactory(T* ptr)
      : ptr_(ptr), self_ref_(WrapUnique(new TrackedRef<T>(ptr_, this))) {
    DCHECK(ptr_);
  }

  ~TrackedRefFactory() {
    // Enter the destruction phase.
    ready_to_destroy_ = std::make_unique<WaitableEvent>();

    // Release self-ref (if this was the last one it will signal the event right
    // away).
    self_ref_.reset();

    ready_to_destroy_->Wait();
  }

  TrackedRef<T> GetTrackedRef() {
    // TrackedRefs cannot be obtained after |live_tracked_refs_| has already
    // reached zero. In other words, the owner of a TrackedRefFactory shouldn't
    // vend new TrackedRefs while it's being destroyed (owners of TrackedRefs
    // may still copy/move their refs around during the destruction phase).
    DCHECK(!live_tracked_refs_.IsZero());
    return TrackedRef<T>(ptr_, this);
  }

 private:
  friend class TrackedRef<T>;
  FRIEND_TEST_ALL_PREFIXES(TrackedRefTest, CopyAndMoveSemantics);

  T* const ptr_;

  // The number of live TrackedRefs vended by this factory.
  AtomicRefCount live_tracked_refs_{0};

  // Non-null during the destruction phase. Signaled once |live_tracked_refs_|
  // reaches 0. Note: while this could a direct member, only initializing it in
  // the destruction phase avoids keeping a handle open for the entire session.
  std::unique_ptr<WaitableEvent> ready_to_destroy_;

  // TrackedRefFactory holds a TrackedRef as well to prevent
  // |live_tracked_refs_| from ever reaching zero before ~TrackedRefFactory().
  std::unique_ptr<TrackedRef<T>> self_ref_;

  DISALLOW_COPY_AND_ASSIGN(TrackedRefFactory);
};

}  // namespace internal
}  // namespace base

#endif  // BASE_TASK_SCHEDULER_TRACKED_REF_H_
