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