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