Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: mojo/edk/system/ports/node.h

Issue 1585493002: [mojo] Ports EDK (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_EDK_SYSTEM_PORTS_NODE_H_
6 #define MOJO_EDK_SYSTEM_PORTS_NODE_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <queue>
12 #include <unordered_map>
13
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/synchronization/lock.h"
17 #include "mojo/edk/system/ports/event.h"
18 #include "mojo/edk/system/ports/hash_functions.h"
19 #include "mojo/edk/system/ports/message.h"
20 #include "mojo/edk/system/ports/name.h"
21 #include "mojo/edk/system/ports/port.h"
22 #include "mojo/edk/system/ports/port_ref.h"
23 #include "mojo/edk/system/ports/user_data.h"
24
25 #undef SendMessage // Gah, windows
26
27 namespace mojo {
28 namespace edk {
29 namespace ports {
30
31 enum : int {
32 OK = 0,
33 ERROR_PORT_UNKNOWN = -10,
34 ERROR_PORT_EXISTS = -11,
35 ERROR_PORT_STATE_UNEXPECTED = -12,
36 ERROR_PORT_CANNOT_SEND_SELF = -13,
37 ERROR_PORT_PEER_CLOSED = -14,
38 ERROR_PORT_CANNOT_SEND_PEER = -15,
39 ERROR_NOT_IMPLEMENTED = -100,
40 };
41
42 struct PortStatus {
43 bool has_messages;
44 bool receiving_messages;
45 bool peer_closed;
46 };
47
48 class NodeDelegate;
49
50 class Node {
51 public:
52 // Does not take ownership of the delegate.
53 Node(const NodeName& name, NodeDelegate* delegate);
54 ~Node();
55
56 // Returns true iff there are no open ports referring to another node or ports
57 // in the process of being transferred from this node to another. If this
58 // returns false, then to ensure clean shutdown, it is necessary to keep the
59 // node alive and continue routing messages to it via AcceptMessage. This
60 // method may be called again after AcceptMessage to check if the Node is now
61 // ready to be destroyed.
62 //
63 // If |allow_local_ports| is |true|, this will only return |false| when there
64 // are transient ports referring to other nodes.
65 bool CanShutdownCleanly(bool allow_local_ports);
66
67 // Lookup the named port.
68 int GetPort(const PortName& port_name, PortRef* port_ref);
69
70 // Creates a port on this node. Before the port can be used, it must be
71 // initialized using InitializePort. This method is useful for bootstrapping
72 // a connection between two nodes. Generally, ports are created using
73 // CreatePortPair instead.
74 int CreateUninitializedPort(PortRef* port_ref);
75
76 // Initializes a newly created port.
77 int InitializePort(const PortRef& port_ref,
78 const NodeName& peer_node_name,
79 const PortName& peer_port_name);
80
81 // Generates a new connected pair of ports bound to this node. These ports
82 // are initialized and ready to go.
83 int CreatePortPair(PortRef* port0_ref, PortRef* port1_ref);
84
85 // User data associated with the port.
86 int SetUserData(const PortRef& port_ref,
87 const scoped_refptr<UserData>& user_data);
88 int GetUserData(const PortRef& port_ref,
89 scoped_refptr<UserData>* user_data);
90
91 // Prevents further messages from being sent from this port or delivered to
92 // this port. The port is removed, and the port's peer is notified of the
93 // closure after it has consumed all pending messages.
94 int ClosePort(const PortRef& port_ref);
95
96 // Returns the current status of the port.
97 int GetStatus(const PortRef& port_ref, PortStatus* port_status);
98
99 // Returns the next available message on the specified port or returns a null
100 // message if there are none available. Returns ERROR_PORT_PEER_CLOSED to
101 // indicate that this port's peer has closed. In such cases GetMessage may
102 // be called until it yields a null message, indicating that no more messages
103 // may be read from the port.
104 int GetMessage(const PortRef& port_ref, ScopedMessage* message);
105
106 // Like GetMessage, but the caller may optionally supply a selector function
107 // that decides whether or not to return the message. If |selector| is a
108 // nullptr, then GetMessageIf acts just like GetMessage. The |selector| may
109 // not call any Node methods.
110 int GetMessageIf(const PortRef& port_ref,
111 std::function<bool(const Message&)> selector,
112 ScopedMessage* message);
113
114 // Sends a message from the specified port to its peer. Note that the message
115 // notification may arrive synchronously (via PortStatusChanged() on the
116 // delegate) if the peer is local to this Node.
117 //
118 // If send fails for any reason, |message| is left unchanged. On success,
119 // ownserhip is transferred and |message| is reset.
120 int SendMessage(const PortRef& port_ref, ScopedMessage* message);
121
122 // Corresponding to NodeDelegate::ForwardMessage.
123 int AcceptMessage(ScopedMessage message);
124
125 // Called to inform this node that communication with another node is lost
126 // indefinitely. This triggers cleanup of ports bound to this node.
127 int LostConnectionToNode(const NodeName& node_name);
128
129 private:
130 int OnUserMessage(ScopedMessage message);
131 int OnPortAccepted(const PortName& port_name);
132 int OnObserveProxy(const PortName& port_name,
133 const ObserveProxyEventData& event);
134 int OnObserveProxyAck(const PortName& port_name, uint64_t last_sequence_num);
135 int OnObserveClosure(const PortName& port_name, uint64_t last_sequence_num);
136
137 int AddPortWithName(const PortName& port_name,
138 const scoped_refptr<Port>& port);
139 void ErasePort(const PortName& port_name);
140 void ErasePort_Locked(const PortName& port_name);
141 scoped_refptr<Port> GetPort(const PortName& port_name);
142 scoped_refptr<Port> GetPort_Locked(const PortName& port_name);
143
144 void WillSendPort_Locked(Port* port,
145 const NodeName& to_node_name,
146 PortName* port_name,
147 PortDescriptor* port_descriptor);
148 int AcceptPort(const PortName& port_name,
149 const PortDescriptor& port_descriptor);
150
151 int WillSendMessage_Locked(Port* port,
152 const PortName& port_name,
153 Message* message);
154 int ForwardMessages_Locked(Port* port, const PortName& port_name);
155 void InitiateProxyRemoval_Locked(Port* port, const PortName& port_name);
156 void MaybeRemoveProxy_Locked(Port* port, const PortName& port_name);
157
158 ScopedMessage NewInternalMessage_Helper(const PortName& port_name,
159 const EventType& type,
160 const void* data,
161 size_t num_data_bytes);
162
163 ScopedMessage NewInternalMessage(const PortName& port_name,
164 const EventType& type) {
165 return NewInternalMessage_Helper(port_name, type, nullptr, 0);
166 }
167
168 template <typename EventData>
169 ScopedMessage NewInternalMessage(const PortName& port_name,
170 const EventType& type,
171 const EventData& data) {
172 return NewInternalMessage_Helper(port_name, type, &data, sizeof(data));
173 }
174
175 const NodeName name_;
176 NodeDelegate* const delegate_;
177
178 // Guards |ports_| as well as any operation which needs to hold multiple port
179 // locks simultaneously. Usage of this is subtle: it must NEVER be acquired
180 // after a Port lock is acquired, and it must ALWAYS be acquired before
181 // calling WillSendMessage_Locked or ForwardMessages_Locked.
182 base::Lock ports_lock_;
183 std::unordered_map<PortName, scoped_refptr<Port>> ports_;
184
185 DISALLOW_COPY_AND_ASSIGN(Node);
186 };
187
188 } // namespace ports
189 } // namespace edk
190 } // namespace mojo
191
192 #endif // MOJO_EDK_SYSTEM_PORTS_NODE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698