| Index: third_party/mojo/src/mojo/edk/system/dispatcher.h
 | 
| diff --git a/third_party/mojo/src/mojo/edk/system/dispatcher.h b/third_party/mojo/src/mojo/edk/system/dispatcher.h
 | 
| index 98b39f43a3f0b2f65daf27a55b2d300b2cc8e2e4..ed6999dc160981f4f42054a4099a8a0eb91c4810 100644
 | 
| --- a/third_party/mojo/src/mojo/edk/system/dispatcher.h
 | 
| +++ b/third_party/mojo/src/mojo/edk/system/dispatcher.h
 | 
| @@ -13,10 +13,10 @@
 | 
|  
 | 
|  #include "base/memory/ref_counted.h"
 | 
|  #include "base/memory/scoped_ptr.h"
 | 
| +#include "base/synchronization/lock.h"
 | 
|  #include "mojo/edk/embedder/platform_handle_vector.h"
 | 
|  #include "mojo/edk/system/handle_signals_state.h"
 | 
|  #include "mojo/edk/system/memory.h"
 | 
| -#include "mojo/edk/system/mutex.h"
 | 
|  #include "mojo/edk/system/system_impl_export.h"
 | 
|  #include "mojo/public/c/system/buffer.h"
 | 
|  #include "mojo/public/c/system/data_pipe.h"
 | 
| @@ -54,9 +54,9 @@
 | 
|  
 | 
|  // A |Dispatcher| implements Mojo primitives that are "attached" to a particular
 | 
|  // handle. This includes most (all?) primitives except for |MojoWait...()|. This
 | 
| -// object is thread-safe, with its state being protected by a single mutex
 | 
| -// |mutex_|, which is also made available to implementation subclasses (via the
 | 
| -// |mutex()| method).
 | 
| +// object is thread-safe, with its state being protected by a single lock
 | 
| +// |lock_|, which is also made available to implementation subclasses (via the
 | 
| +// |lock()| method).
 | 
|  class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
 | 
|      : public base::RefCountedThreadSafe<Dispatcher> {
 | 
|   public:
 | 
| @@ -73,9 +73,9 @@
 | 
|    virtual Type GetType() const = 0;
 | 
|  
 | 
|    // These methods implement the various primitives named |Mojo...()|. These
 | 
| -  // take |mutex_| and handle races with |Close()|. Then they call out to
 | 
| -  // subclasses' |...ImplNoLock()| methods (still under |mutex_|), which
 | 
| -  // actually implement the primitives.
 | 
| +  // take |lock_| and handle races with |Close()|. Then they call out to
 | 
| +  // subclasses' |...ImplNoLock()| methods (still under |lock_|), which actually
 | 
| +  // implement the primitives.
 | 
|    // NOTE(vtl): This puts a big lock around each dispatcher (i.e., handle), and
 | 
|    // prevents the various |...ImplNoLock()|s from releasing the lock as soon as
 | 
|    // possible. If this becomes an issue, we can rethink this.
 | 
| @@ -221,100 +221,91 @@
 | 
|    virtual ~Dispatcher();
 | 
|  
 | 
|    // These are to be overridden by subclasses (if necessary). They are called
 | 
| -  // exactly once (first |CancelAllAwakablesNoLock()|, then |CloseImplNoLock()|)
 | 
| -  // when the dispatcher is being closed.
 | 
| -  virtual void CancelAllAwakablesNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| -  virtual void CloseImplNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| -
 | 
| +  // exactly once -- first |CancelAllAwakablesNoLock()|, then
 | 
| +  // |CloseImplNoLock()|,
 | 
| +  // when the dispatcher is being closed. They are called under |lock_|.
 | 
| +  virtual void CancelAllAwakablesNoLock();
 | 
| +  virtual void CloseImplNoLock();
 | 
|    virtual scoped_refptr<Dispatcher>
 | 
| -  CreateEquivalentDispatcherAndCloseImplNoLock()
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) = 0;
 | 
| +  CreateEquivalentDispatcherAndCloseImplNoLock() = 0;
 | 
|  
 | 
|    // These are to be overridden by subclasses (if necessary). They are never
 | 
| -  // called after the dispatcher has been closed. See the descriptions of the
 | 
| -  // methods without the "ImplNoLock" for more information.
 | 
| +  // called after the dispatcher has been closed. They are called under |lock_|.
 | 
| +  // See the descriptions of the methods without the "ImplNoLock" for more
 | 
| +  // information.
 | 
|    virtual MojoResult WriteMessageImplNoLock(
 | 
|        UserPointer<const void> bytes,
 | 
|        uint32_t num_bytes,
 | 
|        std::vector<DispatcherTransport>* transports,
 | 
| -      MojoWriteMessageFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +      MojoWriteMessageFlags flags);
 | 
|    virtual MojoResult ReadMessageImplNoLock(UserPointer<void> bytes,
 | 
|                                             UserPointer<uint32_t> num_bytes,
 | 
|                                             DispatcherVector* dispatchers,
 | 
|                                             uint32_t* num_dispatchers,
 | 
| -                                           MojoReadMessageFlags flags)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +                                           MojoReadMessageFlags flags);
 | 
|    virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
 | 
|                                           UserPointer<uint32_t> num_bytes,
 | 
| -                                         MojoWriteDataFlags flags)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +                                         MojoWriteDataFlags flags);
 | 
|    virtual MojoResult BeginWriteDataImplNoLock(
 | 
|        UserPointer<void*> buffer,
 | 
|        UserPointer<uint32_t> buffer_num_bytes,
 | 
| -      MojoWriteDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| -  virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +      MojoWriteDataFlags flags);
 | 
| +  virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written);
 | 
|    virtual MojoResult ReadDataImplNoLock(UserPointer<void> elements,
 | 
|                                          UserPointer<uint32_t> num_bytes,
 | 
| -                                        MojoReadDataFlags flags)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +                                        MojoReadDataFlags flags);
 | 
|    virtual MojoResult BeginReadDataImplNoLock(
 | 
|        UserPointer<const void*> buffer,
 | 
|        UserPointer<uint32_t> buffer_num_bytes,
 | 
| -      MojoReadDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| -  virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +      MojoReadDataFlags flags);
 | 
| +  virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read);
 | 
|    virtual MojoResult DuplicateBufferHandleImplNoLock(
 | 
|        UserPointer<const MojoDuplicateBufferHandleOptions> options,
 | 
| -      scoped_refptr<Dispatcher>* new_dispatcher)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +      scoped_refptr<Dispatcher>* new_dispatcher);
 | 
|    virtual MojoResult MapBufferImplNoLock(
 | 
|        uint64_t offset,
 | 
|        uint64_t num_bytes,
 | 
|        MojoMapBufferFlags flags,
 | 
| -      scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| -  virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const
 | 
| -      MOJO_SHARED_LOCKS_REQUIRED(mutex_);
 | 
| +      scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping);
 | 
| +  virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const;
 | 
|    virtual MojoResult AddAwakableImplNoLock(Awakable* awakable,
 | 
|                                             MojoHandleSignals signals,
 | 
|                                             uint32_t context,
 | 
| -                                           HandleSignalsState* signals_state)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +                                           HandleSignalsState* signals_state);
 | 
|    virtual void RemoveAwakableImplNoLock(Awakable* awakable,
 | 
| -                                        HandleSignalsState* signals_state)
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +                                        HandleSignalsState* signals_state);
 | 
|  
 | 
|    // These implement the API used to serialize dispatchers to a |Channel|
 | 
|    // (described below). They will only be called on a dispatcher that's attached
 | 
|    // to and "owned" by a |MessageInTransit|. See the non-"impl" versions for
 | 
|    // more information.
 | 
|    //
 | 
| -  // Note: |StartSerializeImplNoLock()| is actually called with |mutex_| NOT
 | 
| +  // Note: |StartSerializeImplNoLock()| is actually called with |lock_| NOT
 | 
|    // held, since the dispatcher should only be accessible to the calling thread.
 | 
| -  // On Debug builds, |EndSerializeAndCloseImplNoLock()| is called with |mutex_|
 | 
| -  // held, to satisfy any |mutex_.AssertHeld()| (e.g., in |CloseImplNoLock()| --
 | 
| -  // and anything it calls); disentangling those assertions is
 | 
| +  // On Debug builds, |EndSerializeAndCloseImplNoLock()| is called with |lock_|
 | 
| +  // held, to satisfy any |lock_.AssertAcquired()| (e.g., in |CloseImplNoLock()|
 | 
| +  // -- and anything it calls); disentangling those assertions is
 | 
|    // difficult/fragile, and would weaken our general checking of invariants.
 | 
|    //
 | 
|    // TODO(vtl): Consider making these pure virtual once most things support
 | 
|    // being passed over a message pipe.
 | 
|    virtual void StartSerializeImplNoLock(Channel* channel,
 | 
|                                          size_t* max_size,
 | 
| -                                        size_t* max_platform_handles)
 | 
| -      MOJO_NOT_THREAD_SAFE;
 | 
| +                                        size_t* max_platform_handles);
 | 
|    virtual bool EndSerializeAndCloseImplNoLock(
 | 
|        Channel* channel,
 | 
|        void* destination,
 | 
|        size_t* actual_size,
 | 
| -      embedder::PlatformHandleVector* platform_handles) MOJO_NOT_THREAD_SAFE;
 | 
| +      embedder::PlatformHandleVector* platform_handles);
 | 
|  
 | 
|    // This should be overridden to return true if/when there's an ongoing
 | 
|    // operation (e.g., two-phase read/writes on data pipes) that should prevent a
 | 
|    // handle from being sent over a message pipe (with status "busy").
 | 
| -  virtual bool IsBusyNoLock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_);
 | 
| -
 | 
| -  Mutex& mutex() const MOJO_LOCK_RETURNED(mutex_) { return mutex_; }
 | 
| +  virtual bool IsBusyNoLock() const;
 | 
| +
 | 
| +  // Available to subclasses. (Note: Returns a non-const reference, just like
 | 
| +  // |base::AutoLock|'s constructor takes a non-const reference.)
 | 
| +  base::Lock& lock() const { return lock_; }
 | 
|  
 | 
|   private:
 | 
|    friend class DispatcherTransport;
 | 
| @@ -323,28 +314,19 @@
 | 
|    // the dispatcher must not be closed already. (This is the "equivalent" of
 | 
|    // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the
 | 
|    // dispatcher must be disposed of instead of "transferred".)
 | 
| -  void CloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +  void CloseNoLock();
 | 
|  
 | 
|    // Creates an equivalent dispatcher -- representing the same resource as this
 | 
|    // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this
 | 
|    // dispatcher will look as though it was closed, but the resource it
 | 
|    // represents will be assigned to the new dispatcher. This must be called
 | 
|    // under the dispatcher's lock.
 | 
| -  scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock()
 | 
| -      MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 | 
| +  scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock();
 | 
|  
 | 
|    // API to serialize dispatchers to a |Channel|, exposed to only
 | 
|    // |TransportData| (via |TransportData|). They may only be called on a
 | 
|    // dispatcher attached to a |MessageInTransit| (and in particular not in
 | 
|    // |CoreImpl|'s handle table).
 | 
| -  //
 | 
| -  // TODO(vtl): The serialization API (and related implementation methods,
 | 
| -  // including |DispatcherTransport|'s methods) is marked
 | 
| -  // |MOJO_NOT_THREAD_SAFE|. This is because the threading requirements are
 | 
| -  // somewhat complicated (e.g., |HandleTableAccess::TryStartTransport()| is
 | 
| -  // really a try-lock function, amongst other things). We could/should do a
 | 
| -  // more careful job annotating these methods.
 | 
| -  // https://github.com/domokit/mojo/issues/322
 | 
|    //
 | 
|    // Starts the serialization. Returns (via the two "out" parameters) the
 | 
|    // maximum amount of space that may be needed to serialize this dispatcher to
 | 
| @@ -358,7 +340,7 @@
 | 
|    // dispatcher cannot be serialized to the given |Channel|).
 | 
|    void StartSerialize(Channel* channel,
 | 
|                        size_t* max_size,
 | 
| -                      size_t* max_platform_handles) MOJO_NOT_THREAD_SAFE;
 | 
| +                      size_t* max_platform_handles);
 | 
|    // Completes the serialization of this dispatcher to the given |Channel| and
 | 
|    // closes it. (This call will always follow an earlier call to
 | 
|    // |StartSerialize()|, with the same |Channel|.) This does so by writing to
 | 
| @@ -373,13 +355,12 @@
 | 
|    bool EndSerializeAndClose(Channel* channel,
 | 
|                              void* destination,
 | 
|                              size_t* actual_size,
 | 
| -                            embedder::PlatformHandleVector* platform_handles)
 | 
| -      MOJO_NOT_THREAD_SAFE;
 | 
| +                            embedder::PlatformHandleVector* platform_handles);
 | 
|  
 | 
|    // This protects the following members as well as any state added by
 | 
|    // subclasses.
 | 
| -  mutable Mutex mutex_;
 | 
| -  bool is_closed_ MOJO_GUARDED_BY(mutex_);
 | 
| +  mutable base::Lock lock_;
 | 
| +  bool is_closed_;
 | 
|  
 | 
|    MOJO_DISALLOW_COPY_AND_ASSIGN(Dispatcher);
 | 
|  };
 | 
| @@ -394,15 +375,12 @@
 | 
|   public:
 | 
|    DispatcherTransport() : dispatcher_(nullptr) {}
 | 
|  
 | 
| -  void End() MOJO_NOT_THREAD_SAFE;
 | 
| +  void End();
 | 
|  
 | 
|    Dispatcher::Type GetType() const { return dispatcher_->GetType(); }
 | 
| -  bool IsBusy() const MOJO_NOT_THREAD_SAFE {
 | 
| -    return dispatcher_->IsBusyNoLock();
 | 
| -  }
 | 
| -  void Close() MOJO_NOT_THREAD_SAFE { dispatcher_->CloseNoLock(); }
 | 
| -  scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose()
 | 
| -      MOJO_NOT_THREAD_SAFE {
 | 
| +  bool IsBusy() const { return dispatcher_->IsBusyNoLock(); }
 | 
| +  void Close() { dispatcher_->CloseNoLock(); }
 | 
| +  scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose() {
 | 
|      return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock();
 | 
|    }
 | 
|  
 | 
| 
 |