• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_
6 #define MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <queue>
12 
13 #include "base/macros.h"
14 #include "mojo/edk/system/atomic_flag.h"
15 #include "mojo/edk/system/awakable_list.h"
16 #include "mojo/edk/system/dispatcher.h"
17 #include "mojo/edk/system/message_for_transit.h"
18 #include "mojo/edk/system/ports/port_ref.h"
19 
20 namespace mojo {
21 namespace edk {
22 
23 class NodeController;
24 class PortsMessage;
25 
26 class MessagePipeDispatcher : public Dispatcher {
27  public:
28   // Constructs a MessagePipeDispatcher permanently tied to a specific port.
29   // |connected| must indicate the state of the port at construction time; if
30   // the port is initialized with a peer, |connected| must be true. Otherwise it
31   // must be false.
32   //
33   // A MessagePipeDispatcher may not be transferred while in a disconnected
34   // state, and one can never return to a disconnected once connected.
35   //
36   // |pipe_id| is a unique identifier which can be used to track pipe endpoints
37   // as they're passed around. |endpoint| is either 0 or 1 and again is only
38   // used for tracking pipes (one side is always 0, the other is always 1.)
39   MessagePipeDispatcher(NodeController* node_controller,
40                         const ports::PortRef& port,
41                         uint64_t pipe_id,
42                         int endpoint);
43 
44   // Fuses this pipe with |other|. Returns |true| on success or |false| on
45   // failure. Regardless of the return value, both dispatchers are closed by
46   // this call.
47   bool Fuse(MessagePipeDispatcher* other);
48 
49   // Dispatcher:
50   Type GetType() const override;
51   MojoResult Close() override;
52   MojoResult Watch(MojoHandleSignals signals,
53                    const Watcher::WatchCallback& callback,
54                    uintptr_t context) override;
55   MojoResult CancelWatch(uintptr_t context) override;
56   MojoResult WriteMessage(std::unique_ptr<MessageForTransit> message,
57                           MojoWriteMessageFlags flags) override;
58   MojoResult ReadMessage(std::unique_ptr<MessageForTransit>* message,
59                          uint32_t* num_bytes,
60                          MojoHandle* handles,
61                          uint32_t* num_handles,
62                          MojoReadMessageFlags flags,
63                          bool read_any_size) override;
64   HandleSignalsState GetHandleSignalsState() const override;
65   MojoResult AddAwakable(Awakable* awakable,
66                          MojoHandleSignals signals,
67                          uintptr_t context,
68                          HandleSignalsState* signals_state) override;
69   void RemoveAwakable(Awakable* awakable,
70                       HandleSignalsState* signals_state) override;
71   void StartSerialize(uint32_t* num_bytes,
72                       uint32_t* num_ports,
73                       uint32_t* num_handles) override;
74   bool EndSerialize(void* destination,
75                     ports::PortName* ports,
76                     PlatformHandle* handles) override;
77   bool BeginTransit() override;
78   void CompleteTransitAndClose() override;
79   void CancelTransit() override;
80 
81   static scoped_refptr<Dispatcher> Deserialize(
82       const void* data,
83       size_t num_bytes,
84       const ports::PortName* ports,
85       size_t num_ports,
86       PlatformHandle* handles,
87       size_t num_handles);
88 
89  private:
90   class PortObserverThunk;
91   friend class PortObserverThunk;
92 
93   ~MessagePipeDispatcher() override;
94 
95   MojoResult CloseNoLock();
96   HandleSignalsState GetHandleSignalsStateNoLock() const;
97   void OnPortStatusChanged();
98 
99   // These are safe to access from any thread without locking.
100   NodeController* const node_controller_;
101   const ports::PortRef port_;
102   const uint64_t pipe_id_;
103   const int endpoint_;
104 
105   // Guards access to all the fields below.
106   mutable base::Lock signal_lock_;
107 
108   // This is not the same is |port_transferred_|. It's only held true between
109   // BeginTransit() and Complete/CancelTransit().
110   AtomicFlag in_transit_;
111 
112   bool port_transferred_ = false;
113   AtomicFlag port_closed_;
114   AwakableList awakables_;
115 
116   DISALLOW_COPY_AND_ASSIGN(MessagePipeDispatcher);
117 };
118 
119 }  // namespace edk
120 }  // namespace mojo
121 
122 #endif  // MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_
123