// Copyright 2014 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 "sandbox/linux/services/thread_helpers.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "sandbox/linux/services/proc_util.h"

namespace sandbox {

namespace {

const char kAssertSingleThreadedError[] =
    "Current process is not mono-threaded!";
const char kAssertThreadDoesNotAppearInProcFS[] =
    "Started thread does not appear in /proc";
const char kAssertThreadDoesNotDisappearInProcFS[] =
    "Stopped thread does not disappear in /proc";

bool IsSingleThreadedImpl(int proc_fd) {
  CHECK_LE(0, proc_fd);
  struct stat task_stat;
  int fstat_ret = fstatat(proc_fd, "self/task/", &task_stat, 0);
  PCHECK(0 == fstat_ret);

  // At least "..", "." and the current thread should be present.
  CHECK_LE(3UL, task_stat.st_nlink);
  // Counting threads via /proc/self/task could be racy. For the purpose of
  // determining if the current proces is monothreaded it works: if at any
  // time it becomes monothreaded, it'll stay so.
  return task_stat.st_nlink == 3;
}

bool IsThreadPresentInProcFS(int proc_fd,
                             const std::string& thread_id_dir_str) {
  struct stat task_stat;
  const int fstat_ret =
      fstatat(proc_fd, thread_id_dir_str.c_str(), &task_stat, 0);
  if (fstat_ret < 0) {
    PCHECK(ENOENT == errno);
    return false;
  }
  return true;
}

bool IsNotThreadPresentInProcFS(int proc_fd,
                                const std::string& thread_id_dir_str) {
  return !IsThreadPresentInProcFS(proc_fd, thread_id_dir_str);
}

// Run |cb| in a loop until it returns false. Every time |cb| runs, sleep
// for an exponentially increasing amount of time. |cb| is expected to return
// false very quickly and this will crash if it doesn't happen within ~64ms on
// Debug builds (2s on Release builds).
// This is guaranteed to not sleep more than twice as much as the bare minimum
// amount of time.
void RunWhileTrue(const base::Callback<bool(void)>& cb, const char* message) {
#if defined(NDEBUG)
  // In Release mode, crash after 30 iterations, which means having spent
  // roughly 2s in
  // nanosleep(2) cumulatively.
  const unsigned int kMaxIterations = 30U;
#else
  // In practice, this never goes through more than a couple iterations. In
  // debug mode, crash after 64ms (+ eventually 25 times the granularity of
  // the clock) in nanosleep(2). This ensures that this is not becoming too
  // slow.
  const unsigned int kMaxIterations = 25U;
#endif

  // Run |cb| with an exponential back-off, sleeping 2^iterations nanoseconds
  // in nanosleep(2).
  // Note: the clock may not allow for nanosecond granularity, in this case the
  // first iterations would sleep a tiny bit more instead, which would not
  // change the calculations significantly.
  for (unsigned int i = 0; i < kMaxIterations; ++i) {
    if (!cb.Run()) {
      return;
    }

    // Increase the waiting time exponentially.
    struct timespec ts = {0, 1L << i /* nanoseconds */};
    PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts)));
  }

  LOG(FATAL) << message << " (iterations: " << kMaxIterations << ")";

  NOTREACHED();
}

bool IsMultiThreaded(int proc_fd) {
  return !ThreadHelpers::IsSingleThreaded(proc_fd);
}

enum class ThreadAction { Start, Stop };

bool ChangeThreadStateAndWatchProcFS(
    int proc_fd, base::Thread* thread, ThreadAction action) {
  DCHECK_LE(0, proc_fd);
  DCHECK(thread);
  DCHECK(action == ThreadAction::Start || action == ThreadAction::Stop);

  base::Callback<bool(void)> cb;
  const char* message;

  if (action == ThreadAction::Start) {
    // Should start the thread before calling thread_id().
    if (!thread->Start())
      return false;
  }

  const base::PlatformThreadId thread_id = thread->thread_id();
  const std::string thread_id_dir_str =
      "self/task/" + base::IntToString(thread_id) + "/";

  if (action == ThreadAction::Stop) {
    // The target thread should exist in /proc.
    DCHECK(IsThreadPresentInProcFS(proc_fd, thread_id_dir_str));
    thread->Stop();
  }

  // The kernel is at liberty to wake the thread id futex before updating
  // /proc. Start() above or following Stop(), the thread is started or joined,
  // but entries in /proc may not have been updated.
  if (action == ThreadAction::Start) {
    cb = base::Bind(&IsNotThreadPresentInProcFS, proc_fd, thread_id_dir_str);
    message = kAssertThreadDoesNotAppearInProcFS;
  } else {
    cb = base::Bind(&IsThreadPresentInProcFS, proc_fd, thread_id_dir_str);
    message = kAssertThreadDoesNotDisappearInProcFS;
  }
  RunWhileTrue(cb, message);

  DCHECK_EQ(action == ThreadAction::Start,
            IsThreadPresentInProcFS(proc_fd, thread_id_dir_str));

  return true;
}

}  // namespace

// static
bool ThreadHelpers::IsSingleThreaded(int proc_fd) {
  DCHECK_LE(0, proc_fd);
  return IsSingleThreadedImpl(proc_fd);
}

// static
bool ThreadHelpers::IsSingleThreaded() {
  base::ScopedFD task_fd(ProcUtil::OpenProc());
  return IsSingleThreaded(task_fd.get());
}

// static
void ThreadHelpers::AssertSingleThreaded(int proc_fd) {
  DCHECK_LE(0, proc_fd);
  const base::Callback<bool(void)> cb = base::Bind(&IsMultiThreaded, proc_fd);
  RunWhileTrue(cb, kAssertSingleThreadedError);
}

void ThreadHelpers::AssertSingleThreaded() {
  base::ScopedFD task_fd(ProcUtil::OpenProc());
  AssertSingleThreaded(task_fd.get());
}

// static
bool ThreadHelpers::StartThreadAndWatchProcFS(int proc_fd,
                                              base::Thread* thread) {
  return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Start);
}

// static
bool ThreadHelpers::StopThreadAndWatchProcFS(int proc_fd,
                                             base::Thread* thread) {
  return ChangeThreadStateAndWatchProcFS(proc_fd, thread, ThreadAction::Stop);
}

// static
const char* ThreadHelpers::GetAssertSingleThreadedErrorMessageForTests() {
  return kAssertSingleThreadedError;
}

}  // namespace sandbox
