// Copyright (c) 2012 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/message_loop/message_loop_task_runner.h"

#include <utility>

#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"

namespace base {
namespace internal {

namespace {

#if DCHECK_IS_ON()
// Delays larger than this are often bogus, and a warning should be emitted in
// debug builds to warn developers.  http://crbug.com/450045
constexpr TimeDelta kTaskDelayWarningThreshold = TimeDelta::FromDays(14);
#endif

TimeTicks CalculateDelayedRuntime(const Location& from_here, TimeDelta delay) {
  DLOG_IF(WARNING, delay > kTaskDelayWarningThreshold)
      << "Requesting super-long task delay period of " << delay.InSeconds()
      << " seconds from here: " << from_here.ToString();

  DCHECK_GE(delay, TimeDelta()) << "delay should not be negative";

  return delay > TimeDelta() ? TimeTicks::Now() + delay : TimeTicks();
}

}  // namespace

MessageLoopTaskRunner::MessageLoopTaskRunner(
    std::unique_ptr<SequencedTaskSource::Observer> task_source_observer)
    : task_source_observer_(std::move(task_source_observer)) {}

void MessageLoopTaskRunner::BindToCurrentThread() {
  AutoLock lock(valid_thread_id_lock_);
  DCHECK_EQ(kInvalidThreadId, valid_thread_id_);
  valid_thread_id_ = PlatformThread::CurrentId();
}

void MessageLoopTaskRunner::Shutdown() {
  AutoLock lock(incoming_queue_lock_);
  accept_new_tasks_ = false;
#if defined(STARBOARD)
  // Bug: base MessageLoopTaskRunner does not clear its pending task queues at
  // exit.
  while (!outgoing_queue_.empty()) {
    outgoing_queue_.pop();
  }
  while (!incoming_queue_.empty()) {
    incoming_queue_.pop();
  }
#endif
}

bool MessageLoopTaskRunner::PostDelayedTask(const Location& from_here,
                                            OnceClosure task,
                                            base::TimeDelta delay) {
  return AddToIncomingQueue(from_here, std::move(task), delay,
                            Nestable::kNestable);
}

bool MessageLoopTaskRunner::PostNonNestableDelayedTask(
    const Location& from_here,
    OnceClosure task,
    base::TimeDelta delay) {
  return AddToIncomingQueue(from_here, std::move(task), delay,
                            Nestable::kNonNestable);
}

bool MessageLoopTaskRunner::RunsTasksInCurrentSequence() const {
  AutoLock lock(valid_thread_id_lock_);
  return valid_thread_id_ == PlatformThread::CurrentId();
}

PendingTask MessageLoopTaskRunner::TakeTask() {
  // Must be called on execution sequence, unless clearing tasks from an unbound
  // MessageLoop.
  DCHECK(RunsTasksInCurrentSequence() || valid_thread_id_ == kInvalidThreadId);

  // HasTasks() will reload the queue if necessary (there should always be
  // pending tasks by contract).
  const bool has_tasks = HasTasks();
  DCHECK(has_tasks);

  PendingTask pending_task = std::move(outgoing_queue_.front());
  outgoing_queue_.pop();
  return pending_task;
}

bool MessageLoopTaskRunner::HasTasks() {
  // Must be called on execution sequence, unless clearing tasks from an unbound
  // MessageLoop.
  DCHECK(RunsTasksInCurrentSequence() || valid_thread_id_ == kInvalidThreadId);

  if (outgoing_queue_.empty()) {
    AutoLock lock(incoming_queue_lock_);
    incoming_queue_.swap(outgoing_queue_);
    outgoing_queue_empty_ = outgoing_queue_.empty();
  }

  return !outgoing_queue_.empty();
}

void MessageLoopTaskRunner::InjectTask(OnceClosure task) {
  // Must be called on execution sequence, unless clearing tasks from an unbound
  // MessageLoop.
  DCHECK(RunsTasksInCurrentSequence() || valid_thread_id_ == kInvalidThreadId);

  bool success = this->PostTask(FROM_HERE, std::move(task));
  DCHECK(success) << "Injected a task in a dead task runner.";
}

void MessageLoopTaskRunner::SetAddQueueTimeToTasks(bool enable) {
  base::subtle::NoBarrier_Store(&add_queue_time_to_tasks_, enable ? 1 : 0);
}

MessageLoopTaskRunner::~MessageLoopTaskRunner() = default;

bool MessageLoopTaskRunner::AddToIncomingQueue(const Location& from_here,
                                               OnceClosure task,
                                               TimeDelta delay,
                                               Nestable nestable) {
  DCHECK(task_source_observer_)
      << "SetObserver() must be called before posting tasks";

  // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
  // for details.
  CHECK(task);

  PendingTask pending_task(from_here, std::move(task),
                           CalculateDelayedRuntime(from_here, delay), nestable);

  if (base::subtle::NoBarrier_Load(&add_queue_time_to_tasks_)) {
    if (pending_task.delayed_run_time.is_null()) {
      pending_task.queue_time = base::TimeTicks::Now();
    } else {
      pending_task.queue_time = pending_task.delayed_run_time - delay;
    }
  }

#if defined(OS_WIN)
  // We consider the task needs a high resolution timer if the delay is
  // more than 0 and less than 32ms. This caps the relative error to
  // less than 50% : a 33ms wait can wake at 48ms since the default
  // resolution on Windows is between 10 and 15ms.
  if (delay > TimeDelta() &&
      delay.InMilliseconds() < (2 * Time::kMinLowResolutionThresholdMs)) {
    pending_task.is_high_res = true;
  }
#endif

  bool did_queue_task = false;
  bool was_empty;
  {
    AutoLock auto_lock(incoming_queue_lock_);
    if (accept_new_tasks_) {
      // Initialize the sequence number. The sequence number is used for delayed
      // tasks (to facilitate FIFO sorting when two tasks have the same
      // delayed_run_time value) and for identifying the task in about:tracing.
      pending_task.sequence_num = next_sequence_num_++;

      task_source_observer_->WillQueueTask(&pending_task);

      was_empty = outgoing_queue_empty_ && incoming_queue_.empty();
      incoming_queue_.push(std::move(pending_task));

      did_queue_task = true;
    }
  }

  if (!did_queue_task) {
    // Clear the pending task outside of |incoming_queue_lock_| to prevent any
    // chance of self-deadlock if destroying a task also posts a task to this
    // queue.
    pending_task.task.Reset();
    return false;
  }

  // Let |task_source_observer_| know about the task just queued. It's important
  // to do this outside of |incoming_queue_lock_| to avoid blocking tasks
  // incoming from other threads on the resolution of DidQueueTask().
  task_source_observer_->DidQueueTask(was_empty);
  return true;
}

}  // namespace internal

}  // namespace base
