1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "mojo/public/cpp/bindings/sync_call_restrictions.h" 6 7 #if ENABLE_SYNC_CALL_RESTRICTIONS 8 9 #include "base/debug/leak_annotations.h" 10 #include "base/logging.h" 11 #include "base/macros.h" 12 #include "base/no_destructor.h" 13 #include "base/synchronization/lock.h" 14 #include "base/threading/sequence_local_storage_slot.h" 15 #include "mojo/public/c/system/core.h" 16 17 namespace mojo { 18 19 namespace { 20 21 class GlobalSyncCallSettings { 22 public: 23 GlobalSyncCallSettings() = default; 24 ~GlobalSyncCallSettings() = default; 25 sync_call_allowed_by_default() const26 bool sync_call_allowed_by_default() const { 27 base::AutoLock lock(lock_); 28 return sync_call_allowed_by_default_; 29 } 30 DisallowSyncCallByDefault()31 void DisallowSyncCallByDefault() { 32 base::AutoLock lock(lock_); 33 sync_call_allowed_by_default_ = false; 34 } 35 36 private: 37 mutable base::Lock lock_; 38 bool sync_call_allowed_by_default_ = true; 39 40 DISALLOW_COPY_AND_ASSIGN(GlobalSyncCallSettings); 41 }; 42 GetGlobalSettings()43GlobalSyncCallSettings& GetGlobalSettings() { 44 static base::NoDestructor<GlobalSyncCallSettings> global_settings; 45 return *global_settings; 46 } 47 GetSequenceLocalScopedAllowCount()48size_t& GetSequenceLocalScopedAllowCount() { 49 static base::NoDestructor<base::SequenceLocalStorageSlot<size_t>> count; 50 return count->Get(); 51 } 52 53 } // namespace 54 55 // static AssertSyncCallAllowed()56void SyncCallRestrictions::AssertSyncCallAllowed() { 57 if (GetGlobalSettings().sync_call_allowed_by_default()) 58 return; 59 if (GetSequenceLocalScopedAllowCount() > 0) 60 return; 61 62 LOG(FATAL) << "Mojo sync calls are not allowed in this process because " 63 << "they can lead to jank and deadlock. If you must make an " 64 << "exception, please see " 65 << "SyncCallRestrictions::ScopedAllowSyncCall and consult " 66 << "mojo/OWNERS."; 67 } 68 69 // static DisallowSyncCall()70void SyncCallRestrictions::DisallowSyncCall() { 71 GetGlobalSettings().DisallowSyncCallByDefault(); 72 } 73 74 // static IncreaseScopedAllowCount()75void SyncCallRestrictions::IncreaseScopedAllowCount() { 76 ++GetSequenceLocalScopedAllowCount(); 77 } 78 79 // static DecreaseScopedAllowCount()80void SyncCallRestrictions::DecreaseScopedAllowCount() { 81 DCHECK_GT(GetSequenceLocalScopedAllowCount(), 0u); 82 --GetSequenceLocalScopedAllowCount(); 83 } 84 85 } // namespace mojo 86 87 #endif // ENABLE_SYNC_CALL_RESTRICTIONS 88