• 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
7 
8 #include "base/macros.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "mojo/public/cpp/bindings/bindings_export.h"
11 
12 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
13 #define ENABLE_SYNC_CALL_RESTRICTIONS 1
14 #else
15 #define ENABLE_SYNC_CALL_RESTRICTIONS 0
16 #endif
17 
18 class ChromeSelectFileDialogFactory;
19 
20 namespace sync_preferences {
21 class PrefServiceSyncable;
22 }
23 
24 namespace content {
25 class BlinkTestController;
26 }
27 
28 namespace display {
29 class ForwardingDisplayDelegate;
30 }
31 
32 namespace leveldb {
33 class LevelDBMojoProxy;
34 }
35 
36 namespace prefs {
37 class PersistentPrefStoreClient;
38 }
39 
40 namespace ui {
41 class ClipboardClient;
42 class HostContextFactoryPrivate;
43 }  // namespace ui
44 
45 namespace viz {
46 class HostFrameSinkManager;
47 }
48 
49 namespace mojo {
50 class ScopedAllowSyncCallForTesting;
51 
52 // In some processes, sync calls are disallowed. For example, in the browser
53 // process we don't want any sync calls to child processes for performance,
54 // security and stability reasons. SyncCallRestrictions helps to enforce such
55 // rules.
56 //
57 // Before processing a sync call, the bindings call
58 // SyncCallRestrictions::AssertSyncCallAllowed() to check whether sync calls are
59 // allowed. By default sync calls are allowed but they may be globally
60 // disallowed within a process by calling DisallowSyncCall().
61 //
62 // If globally disallowed but you but you have a very compelling reason to
63 // disregard that (which should be very very rare), you can override it by
64 // constructing a ScopedAllowSyncCall object which allows making sync calls on
65 // the current sequence during its lifetime.
66 class MOJO_CPP_BINDINGS_EXPORT SyncCallRestrictions {
67  public:
68 #if ENABLE_SYNC_CALL_RESTRICTIONS
69   // Checks whether the current sequence is allowed to make sync calls, and
70   // causes a DCHECK if not.
71   static void AssertSyncCallAllowed();
72 
73   // Disables sync calls within the calling process. Any caller who wishes to
74   // make sync calls once this has been invoked must do so within the extent of
75   // a ScopedAllowSyncCall or ScopedAllowSyncCallForTesting.
76   static void DisallowSyncCall();
77 
78 #else
79   // Inline the empty definitions of functions so that they can be compiled out.
80   static void AssertSyncCallAllowed() {}
81   static void DisallowSyncCall() {}
82 #endif
83 
84  private:
85   // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
86   // BEGIN ALLOWED USAGE.
87   // SynchronousCompositorHost is used for Android webview.
88   friend class content::SynchronousCompositorHost;
89   // LevelDBMojoProxy makes same-process sync calls from the DB thread.
90   friend class leveldb::LevelDBMojoProxy;
91   // Pref service connection is sync at startup.
92   friend class prefs::PersistentPrefStoreClient;
93   // Incognito pref service instances are created synchronously.
94   friend class sync_preferences::PrefServiceSyncable;
95   friend class mojo::ScopedAllowSyncCallForTesting;
96   // For file open and save dialogs created synchronously.
97   friend class ::ChromeSelectFileDialogFactory;
98   // For synchronous system clipboard access.
99   friend class ui::ClipboardClient;
100   // For destroying the GL context/surface that draw to a platform window before
101   // the platform window is destroyed.
102   friend class viz::HostFrameSinkManager;
103   // Allow for layout test pixel dumps.
104   friend class content::BlinkTestController;
105   // For preventing frame swaps of wrong size during resize on Windows.
106   // (https://crbug.com/811945)
107   friend class ui::HostContextFactoryPrivate;
108   // END ALLOWED USAGE.
109 
110   // BEGIN USAGE THAT NEEDS TO BE FIXED.
111   // In ash::Shell::Init() it assumes that NativeDisplayDelegate will be
112   // synchronous at first. In mushrome ForwardingDisplayDelegate uses a
113   // synchronous call to get the display snapshots as a workaround.
114   friend class display::ForwardingDisplayDelegate;
115   // END USAGE THAT NEEDS TO BE FIXED.
116 
117 #if ENABLE_SYNC_CALL_RESTRICTIONS
118   static void IncreaseScopedAllowCount();
119   static void DecreaseScopedAllowCount();
120 #else
IncreaseScopedAllowCount()121   static void IncreaseScopedAllowCount() {}
DecreaseScopedAllowCount()122   static void DecreaseScopedAllowCount() {}
123 #endif
124 
125   // If a process is configured to disallow sync calls in general, constructing
126   // a ScopedAllowSyncCall object temporarily allows making sync calls on the
127   // current sequence. Doing this is almost always incorrect, which is why we
128   // limit who can use this through friend. If you find yourself needing to use
129   // this, talk to mojo/OWNERS.
130   class ScopedAllowSyncCall {
131    public:
ScopedAllowSyncCall()132     ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
~ScopedAllowSyncCall()133     ~ScopedAllowSyncCall() { DecreaseScopedAllowCount(); }
134 
135    private:
136 #if ENABLE_SYNC_CALL_RESTRICTIONS
137     base::ThreadRestrictions::ScopedAllowWait allow_wait_;
138 #endif
139 
140     DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCall);
141   };
142 
143   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncCallRestrictions);
144 };
145 
146 class ScopedAllowSyncCallForTesting {
147  public:
ScopedAllowSyncCallForTesting()148   ScopedAllowSyncCallForTesting() {}
~ScopedAllowSyncCallForTesting()149   ~ScopedAllowSyncCallForTesting() {}
150 
151  private:
152   SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_sync_call_;
153 
154   DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCallForTesting);
155 };
156 
157 }  // namespace mojo
158 
159 #endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
160