// Copyright 2016 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 "mojo/public/cpp/bindings/sync_call_restrictions.h"
#if ENABLE_SYNC_CALL_RESTRICTIONS
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/synchronization/lock.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "mojo/public/c/system/core.h"
namespace mojo {
namespace {
class GlobalSyncCallSettings {
public:
GlobalSyncCallSettings() = default;
~GlobalSyncCallSettings() = default;
bool sync_call_allowed_by_default() const {
base::AutoLock lock(lock_);
return sync_call_allowed_by_default_;
}
void DisallowSyncCallByDefault() {
base::AutoLock lock(lock_);
sync_call_allowed_by_default_ = false;
}
private:
mutable base::Lock lock_;
bool sync_call_allowed_by_default_ = true;
DISALLOW_COPY_AND_ASSIGN(GlobalSyncCallSettings);
};
GlobalSyncCallSettings& GetGlobalSettings() {
static base::NoDestructor<GlobalSyncCallSettings> global_settings;
return *global_settings;
}
size_t& GetSequenceLocalScopedAllowCount() {
static base::NoDestructor<base::SequenceLocalStorageSlot<size_t>> count;
return count->Get();
}
} // namespace
// static
void SyncCallRestrictions::AssertSyncCallAllowed() {
if (GetGlobalSettings().sync_call_allowed_by_default())
return;
if (GetSequenceLocalScopedAllowCount() > 0)
return;
LOG(FATAL) << "Mojo sync calls are not allowed in this process because "
<< "they can lead to jank and deadlock. If you must make an "
<< "exception, please see "
<< "SyncCallRestrictions::ScopedAllowSyncCall and consult "
<< "mojo/OWNERS.";
}
// static
void SyncCallRestrictions::DisallowSyncCall() {
GetGlobalSettings().DisallowSyncCallByDefault();
}
// static
void SyncCallRestrictions::IncreaseScopedAllowCount() {
++GetSequenceLocalScopedAllowCount();
}
// static
void SyncCallRestrictions::DecreaseScopedAllowCount() {
DCHECK_GT(GetSequenceLocalScopedAllowCount(), 0u);
--GetSequenceLocalScopedAllowCount();
}
} // namespace mojo
#endif // ENABLE_SYNC_CALL_RESTRICTIONS