// Copyright 2017 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.

#include "base/task_scheduler/lazy_task_runner.h"

#include <utility>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/task_scheduler/post_task.h"

namespace base {
namespace internal {

namespace {
ScopedLazyTaskRunnerListForTesting* g_scoped_lazy_task_runner_list_for_testing =
    nullptr;
}  // namespace

template <typename TaskRunnerType, bool com_sta>
void LazyTaskRunner<TaskRunnerType, com_sta>::Reset() {
  subtle::AtomicWord state = subtle::Acquire_Load(&state_);

  DCHECK_NE(state, kLazyInstanceStateCreating) << "Race: all threads should be "
                                                  "unwound in unittests before "
                                                  "resetting TaskRunners.";

  // Return if no reference is held by this instance.
  if (!state)
    return;

  // Release the reference acquired in Get().
  SequencedTaskRunner* task_runner = reinterpret_cast<TaskRunnerType*>(state);
  task_runner->Release();

  // Clear the state.
  subtle::NoBarrier_Store(&state_, 0);
}

template <>
scoped_refptr<SequencedTaskRunner>
LazyTaskRunner<SequencedTaskRunner, false>::Create() {
  // It is invalid to specify a SingleThreadTaskRunnerThreadMode with a
  // LazySequencedTaskRunner.
  DCHECK_EQ(thread_mode_, SingleThreadTaskRunnerThreadMode::SHARED);

  return CreateSequencedTaskRunnerWithTraits(traits_);
}

template <>
scoped_refptr<SingleThreadTaskRunner>
LazyTaskRunner<SingleThreadTaskRunner, false>::Create() {
  return CreateSingleThreadTaskRunnerWithTraits(traits_, thread_mode_);
}

#if defined(OS_WIN)
template <>
scoped_refptr<SingleThreadTaskRunner>
LazyTaskRunner<SingleThreadTaskRunner, true>::Create() {
  return CreateCOMSTATaskRunnerWithTraits(traits_, thread_mode_);
}
#endif

// static
template <typename TaskRunnerType, bool com_sta>
TaskRunnerType* LazyTaskRunner<TaskRunnerType, com_sta>::CreateRaw(
    void* void_self) {
  auto self =
      reinterpret_cast<LazyTaskRunner<TaskRunnerType, com_sta>*>(void_self);

  scoped_refptr<TaskRunnerType> task_runner = self->Create();

  // Acquire a reference to the TaskRunner. The reference will either
  // never be released or be released in Reset(). The reference is not
  // managed by a scoped_refptr because adding a scoped_refptr member to
  // LazyTaskRunner would prevent its static initialization.
  task_runner->AddRef();

  // Reset this instance when the current
  // ScopedLazyTaskRunnerListForTesting is destroyed, if any.
  if (g_scoped_lazy_task_runner_list_for_testing) {
    g_scoped_lazy_task_runner_list_for_testing->AddCallback(BindOnce(
        &LazyTaskRunner<TaskRunnerType, com_sta>::Reset, Unretained(self)));
  }

  return task_runner.get();
}

template <typename TaskRunnerType, bool com_sta>
scoped_refptr<TaskRunnerType> LazyTaskRunner<TaskRunnerType, com_sta>::Get() {
  return WrapRefCounted(subtle::GetOrCreateLazyPointer(
      &state_, &LazyTaskRunner<TaskRunnerType, com_sta>::CreateRaw,
      reinterpret_cast<void*>(this), nullptr, nullptr));
}

template class LazyTaskRunner<SequencedTaskRunner, false>;
template class LazyTaskRunner<SingleThreadTaskRunner, false>;

#if defined(OS_WIN)
template class LazyTaskRunner<SingleThreadTaskRunner, true>;
#endif

ScopedLazyTaskRunnerListForTesting::ScopedLazyTaskRunnerListForTesting() {
  DCHECK(!g_scoped_lazy_task_runner_list_for_testing);
  g_scoped_lazy_task_runner_list_for_testing = this;
}

ScopedLazyTaskRunnerListForTesting::~ScopedLazyTaskRunnerListForTesting() {
  internal::AutoSchedulerLock auto_lock(lock_);
  for (auto& callback : callbacks_)
    std::move(callback).Run();
  g_scoped_lazy_task_runner_list_for_testing = nullptr;
}

void ScopedLazyTaskRunnerListForTesting::AddCallback(OnceClosure callback) {
  internal::AutoSchedulerLock auto_lock(lock_);
  callbacks_.push_back(std::move(callback));
}

}  // namespace internal
}  // namespace base
