// 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/threading/thread_restrictions.h"

#if DCHECK_IS_ON()

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_local.h"

namespace base {

namespace {

LazyInstance<ThreadLocalBoolean>::Leaky g_blocking_disallowed =
    LAZY_INSTANCE_INITIALIZER;

LazyInstance<ThreadLocalBoolean>::Leaky
    g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER;

LazyInstance<ThreadLocalBoolean>::Leaky g_base_sync_primitives_disallowed =
    LAZY_INSTANCE_INITIALIZER;

LazyInstance<ThreadLocalBoolean>::Leaky g_cpu_intensive_work_disallowed =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

void AssertBlockingAllowed() {
  DCHECK(!g_blocking_disallowed.Get().Get())
      << "Function marked as blocking was called from a scope that disallows "
         "blocking! If this task is running inside the TaskScheduler, it needs "
         "to have MayBlock() in its TaskTraits. Otherwise, consider making "
         "this blocking work asynchronous or, as a last resort, you may use "
         "ScopedAllowBlocking (see its documentation for best practices).";
}

void DisallowBlocking() {
  g_blocking_disallowed.Get().Set(true);
}

ScopedDisallowBlocking::ScopedDisallowBlocking()
    : was_disallowed_(g_blocking_disallowed.Get().Get()) {
  g_blocking_disallowed.Get().Set(true);
}

ScopedDisallowBlocking::~ScopedDisallowBlocking() {
  DCHECK(g_blocking_disallowed.Get().Get());
  g_blocking_disallowed.Get().Set(was_disallowed_);
}

ScopedAllowBlocking::ScopedAllowBlocking()
    : was_disallowed_(g_blocking_disallowed.Get().Get()) {
  g_blocking_disallowed.Get().Set(false);
}

ScopedAllowBlocking::~ScopedAllowBlocking() {
  DCHECK(!g_blocking_disallowed.Get().Get());
  g_blocking_disallowed.Get().Set(was_disallowed_);
}

void DisallowBaseSyncPrimitives() {
  g_base_sync_primitives_disallowed.Get().Set(true);
}

ScopedAllowBaseSyncPrimitives::ScopedAllowBaseSyncPrimitives()
    : was_disallowed_(g_base_sync_primitives_disallowed.Get().Get()) {
  DCHECK(!g_blocking_disallowed.Get().Get())
      << "To allow //base sync primitives in a scope where blocking is "
         "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.";
  g_base_sync_primitives_disallowed.Get().Set(false);
}

ScopedAllowBaseSyncPrimitives::~ScopedAllowBaseSyncPrimitives() {
  DCHECK(!g_base_sync_primitives_disallowed.Get().Get());
  g_base_sync_primitives_disallowed.Get().Set(was_disallowed_);
}

ScopedAllowBaseSyncPrimitivesOutsideBlockingScope::
    ScopedAllowBaseSyncPrimitivesOutsideBlockingScope()
    : was_disallowed_(g_base_sync_primitives_disallowed.Get().Get()) {
  g_base_sync_primitives_disallowed.Get().Set(false);
}

ScopedAllowBaseSyncPrimitivesOutsideBlockingScope::
    ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() {
  DCHECK(!g_base_sync_primitives_disallowed.Get().Get());
  g_base_sync_primitives_disallowed.Get().Set(was_disallowed_);
}

ScopedAllowBaseSyncPrimitivesForTesting::
    ScopedAllowBaseSyncPrimitivesForTesting()
    : was_disallowed_(g_base_sync_primitives_disallowed.Get().Get()) {
  g_base_sync_primitives_disallowed.Get().Set(false);
}

ScopedAllowBaseSyncPrimitivesForTesting::
    ~ScopedAllowBaseSyncPrimitivesForTesting() {
  DCHECK(!g_base_sync_primitives_disallowed.Get().Get());
  g_base_sync_primitives_disallowed.Get().Set(was_disallowed_);
}

namespace internal {

void AssertBaseSyncPrimitivesAllowed() {
  DCHECK(!g_base_sync_primitives_disallowed.Get().Get())
      << "Waiting on a //base sync primitive is not allowed on this thread to "
         "prevent jank and deadlock. If waiting on a //base sync primitive is "
         "unavoidable, do it within the scope of a "
         "ScopedAllowBaseSyncPrimitives. If in a test, "
         "use ScopedAllowBaseSyncPrimitivesForTesting.";
}

void ResetThreadRestrictionsForTesting() {
  g_blocking_disallowed.Get().Set(false);
  g_singleton_disallowed.Get().Set(false);
  g_base_sync_primitives_disallowed.Get().Set(false);
  g_cpu_intensive_work_disallowed.Get().Set(false);
}

}  // namespace internal

void AssertLongCPUWorkAllowed() {
  DCHECK(!g_cpu_intensive_work_disallowed.Get().Get())
      << "Function marked as CPU intensive was called from a scope that "
         "disallows this kind of work! Consider making this work asynchronous.";
}

void DisallowUnresponsiveTasks() {
  DisallowBlocking();
  DisallowBaseSyncPrimitives();
  g_cpu_intensive_work_disallowed.Get().Set(true);
}

ThreadRestrictions::ScopedAllowIO::ScopedAllowIO()
    : was_allowed_(SetIOAllowed(true)) {}

ThreadRestrictions::ScopedAllowIO::~ScopedAllowIO() {
  SetIOAllowed(was_allowed_);
}

// static
bool ThreadRestrictions::SetIOAllowed(bool allowed) {
  bool previous_disallowed = g_blocking_disallowed.Get().Get();
  g_blocking_disallowed.Get().Set(!allowed);
  return !previous_disallowed;
}

#if defined(STARBOARD)
// static
bool ThreadRestrictions::GetSingletonAllowed() {
  return !g_singleton_disallowed.Get().Get();
}
#endif  // defined(STARBOARD)

// static
bool ThreadRestrictions::SetSingletonAllowed(bool allowed) {
  bool previous_disallowed = g_singleton_disallowed.Get().Get();
  g_singleton_disallowed.Get().Set(!allowed);
  return !previous_disallowed;
}

// static
void ThreadRestrictions::AssertSingletonAllowed() {
  if (g_singleton_disallowed.Get().Get()) {
    NOTREACHED() << "LazyInstance/Singleton is not allowed to be used on this "
                 << "thread.  Most likely it's because this thread is not "
                 << "joinable (or the current task is running with "
                 << "TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN semantics), so "
                 << "AtExitManager may have deleted the object on shutdown, "
                 << "leading to a potential shutdown crash. If you need to use "
                 << "the object from this context, it'll have to be updated to "
                 << "use Leaky traits.";
  }
}

// static
void ThreadRestrictions::DisallowWaiting() {
  DisallowBaseSyncPrimitives();
}

bool ThreadRestrictions::SetWaitAllowed(bool allowed) {
  bool previous_disallowed = g_base_sync_primitives_disallowed.Get().Get();
  g_base_sync_primitives_disallowed.Get().Set(!allowed);
  return !previous_disallowed;
}

ThreadRestrictions::ScopedAllowWait::ScopedAllowWait()
    : was_allowed_(SetWaitAllowed(true)) {}

ThreadRestrictions::ScopedAllowWait::~ScopedAllowWait() {
  SetWaitAllowed(was_allowed_);
}

}  // namespace base

#endif  // DCHECK_IS_ON()
