C++程序  |  95行  |  3.17 KB

// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
#define MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_

#include "base/macros.h"
#include "base/threading/thread_restrictions.h"

#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
#define ENABLE_SYNC_CALL_RESTRICTIONS 1
#else
#define ENABLE_SYNC_CALL_RESTRICTIONS 0
#endif

namespace ui {
class GpuService;
}

namespace views {
class ClipboardMus;
}

namespace mojo {

// In some processes, sync calls are disallowed. For example, in the browser
// process we don't want any sync calls to child processes for performance,
// security and stability reasons. SyncCallRestrictions helps to enforce such
// rules.
//
// Before processing a sync call, the bindings call
// SyncCallRestrictions::AssertSyncCallAllowed() to check whether sync calls are
// allowed. By default, it is determined by the mojo system property
// MOJO_PROPERTY_SYNC_CALL_ALLOWED. If the default setting says no but you have
// a very compelling reason to disregard that (which should be very very rare),
// you can override it by constructing a ScopedAllowSyncCall object, which
// allows making sync calls on the current thread during its lifetime.
class SyncCallRestrictions {
 public:
#if ENABLE_SYNC_CALL_RESTRICTIONS
  // Checks whether the current thread is allowed to make sync calls, and causes
  // a DCHECK if not.
  static void AssertSyncCallAllowed();
#else
  // Inline the empty definitions of functions so that they can be compiled out.
  static void AssertSyncCallAllowed() {}
#endif

 private:
  // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
  // BEGIN ALLOWED USAGE.
  friend class ui::GpuService;  // http://crbug.com/620058
  // END ALLOWED USAGE.

  // BEGIN USAGE THAT NEEDS TO BE FIXED.
  // In the non-mus case, we called blocking OS functions in the ui::Clipboard
  // implementation which weren't caught by sync call restrictions. Our blocking
  // calls to mus, however, are.
  friend class views::ClipboardMus;
  // END USAGE THAT NEEDS TO BE FIXED.

#if ENABLE_SYNC_CALL_RESTRICTIONS
  static void IncreaseScopedAllowCount();
  static void DecreaseScopedAllowCount();
#else
  static void IncreaseScopedAllowCount() {}
  static void DecreaseScopedAllowCount() {}
#endif

  // If a process is configured to disallow sync calls in general, constructing
  // a ScopedAllowSyncCall object temporarily allows making sync calls on the
  // current thread. Doing this is almost always incorrect, which is why we
  // limit who can use this through friend. If you find yourself needing to use
  // this, talk to mojo/OWNERS.
  class ScopedAllowSyncCall {
   public:
    ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
    ~ScopedAllowSyncCall() { DecreaseScopedAllowCount(); }

   private:
#if ENABLE_SYNC_CALL_RESTRICTIONS
    base::ThreadRestrictions::ScopedAllowWait allow_wait_;
#endif

    DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCall);
  };

  DISALLOW_IMPLICIT_CONSTRUCTORS(SyncCallRestrictions);
};

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_