Home | History | Annotate | Download | only in bindings
      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
     67   static void IncreaseScopedAllowCount() {}
     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:
     78     ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
     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