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