• 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 
11 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
12 #define ENABLE_SYNC_CALL_RESTRICTIONS 1
13 #else
14 #define ENABLE_SYNC_CALL_RESTRICTIONS 0
15 #endif
16 
17 namespace ui {
18 class GpuService;
19 }
20 
21 namespace views {
22 class ClipboardMus;
23 }
24 
25 namespace mojo {
26 
27 // In some processes, sync calls are disallowed. For example, in the browser
28 // process we don't want any sync calls to child processes for performance,
29 // security and stability reasons. SyncCallRestrictions helps to enforce such
30 // rules.
31 //
32 // Before processing a sync call, the bindings call
33 // SyncCallRestrictions::AssertSyncCallAllowed() to check whether sync calls are
34 // allowed. By default, it is determined by the mojo system property
35 // MOJO_PROPERTY_SYNC_CALL_ALLOWED. If the default setting says no but you have
36 // a very compelling reason to disregard that (which should be very very rare),
37 // you can override it by constructing a ScopedAllowSyncCall object, which
38 // allows making sync calls on the current thread during its lifetime.
39 class SyncCallRestrictions {
40  public:
41 #if ENABLE_SYNC_CALL_RESTRICTIONS
42   // Checks whether the current thread is allowed to make sync calls, and causes
43   // a DCHECK if not.
44   static void AssertSyncCallAllowed();
45 #else
46   // Inline the empty definitions of functions so that they can be compiled out.
47   static void AssertSyncCallAllowed() {}
48 #endif
49 
50  private:
51   // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
52   // BEGIN ALLOWED USAGE.
53   friend class ui::GpuService;  // http://crbug.com/620058
54   // END ALLOWED USAGE.
55 
56   // BEGIN USAGE THAT NEEDS TO BE FIXED.
57   // In the non-mus case, we called blocking OS functions in the ui::Clipboard
58   // implementation which weren't caught by sync call restrictions. Our blocking
59   // calls to mus, however, are.
60   friend class views::ClipboardMus;
61   // END USAGE THAT NEEDS TO BE FIXED.
62 
63 #if ENABLE_SYNC_CALL_RESTRICTIONS
64   static void IncreaseScopedAllowCount();
65   static void DecreaseScopedAllowCount();
66 #else
IncreaseScopedAllowCount()67   static void IncreaseScopedAllowCount() {}
DecreaseScopedAllowCount()68   static void DecreaseScopedAllowCount() {}
69 #endif
70 
71   // If a process is configured to disallow sync calls in general, constructing
72   // a ScopedAllowSyncCall object temporarily allows making sync calls on the
73   // current thread. Doing this is almost always incorrect, which is why we
74   // limit who can use this through friend. If you find yourself needing to use
75   // this, talk to mojo/OWNERS.
76   class ScopedAllowSyncCall {
77    public:
ScopedAllowSyncCall()78     ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
~ScopedAllowSyncCall()79     ~ScopedAllowSyncCall() { DecreaseScopedAllowCount(); }
80 
81    private:
82 #if ENABLE_SYNC_CALL_RESTRICTIONS
83     base::ThreadRestrictions::ScopedAllowWait allow_wait_;
84 #endif
85 
86     DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCall);
87   };
88 
89   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncCallRestrictions);
90 };
91 
92 }  // namespace mojo
93 
94 #endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
95