• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()43 GlobalSyncCallSettings& GetGlobalSettings() {
44   static base::NoDestructor<GlobalSyncCallSettings> global_settings;
45   return *global_settings;
46 }
47 
GetSequenceLocalScopedAllowCount()48 size_t& GetSequenceLocalScopedAllowCount() {
49   static base::NoDestructor<base::SequenceLocalStorageSlot<size_t>> count;
50   return count->Get();
51 }
52 
53 }  // namespace
54 
55 // static
AssertSyncCallAllowed()56 void 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()70 void SyncCallRestrictions::DisallowSyncCall() {
71   GetGlobalSettings().DisallowSyncCallByDefault();
72 }
73 
74 // static
IncreaseScopedAllowCount()75 void SyncCallRestrictions::IncreaseScopedAllowCount() {
76   ++GetSequenceLocalScopedAllowCount();
77 }
78 
79 // static
DecreaseScopedAllowCount()80 void SyncCallRestrictions::DecreaseScopedAllowCount() {
81   DCHECK_GT(GetSequenceLocalScopedAllowCount(), 0u);
82   --GetSequenceLocalScopedAllowCount();
83 }
84 
85 }  // namespace mojo
86 
87 #endif  // ENABLE_SYNC_CALL_RESTRICTIONS
88