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 #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
     74   static void IncreaseScopedAllowCount() {}
     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:
     85     ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
     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