OLD | NEW |
---|---|
(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_CHANNEL_H_ | |
6 #define MOJO_EDK_SYSTEM_CHANNEL_H_ | |
7 | |
8 #include "base/logging.h" | |
9 #include "base/macros.h" | |
10 #include "base/memory/ref_counted.h" | |
11 #include "base/task_runner.h" | |
12 #include "mojo/edk/embedder/platform_handle_vector.h" | |
13 #include "mojo/edk/embedder/scoped_platform_handle.h" | |
14 | |
15 namespace mojo { | |
16 namespace edk { | |
17 | |
18 const size_t kChannelMessageAlignment = 8; | |
19 | |
20 // Channel provides a thread-safe interface to read and write arbitrary | |
21 // delimited messages over an underlying I/O channel, optionally transferring | |
22 // one or more platform handles in the process. | |
23 class Channel : public base::RefCountedThreadSafe<Channel> { | |
24 public: | |
25 struct Message; | |
26 | |
27 using MessagePtr = scoped_ptr<Message>; | |
28 | |
29 // A message to be written to a channel. | |
30 struct Message { | |
31 struct Header { | |
32 // Message size in bytes, including the header. | |
33 uint32_t num_bytes; | |
34 | |
35 // Number of attached handles. | |
36 uint16_t num_handles; | |
37 | |
38 // Zero | |
39 uint16_t padding; | |
40 }; | |
41 | |
42 // Allocates and owns a buffer for message data with enough capacity for | |
43 // |payload_size| bytes plus a header. Takes ownership of |handles|, which | |
44 // may be null. | |
45 Message(size_t payload_size, size_t num_handles); | |
46 | |
47 ~Message(); | |
48 | |
49 // Constructs a Message from serialized message data. | |
50 static MessagePtr Deserialize(const void* data, size_t data_num_bytes); | |
51 | |
52 const void* data() const { return data_; } | |
53 size_t data_num_bytes() const { return size_; } | |
54 | |
55 void* mutable_payload() { return static_cast<void*>(header_ + 1); } | |
56 const void* payload() const { | |
57 return static_cast<const void*>(header_ + 1); | |
58 } | |
59 size_t payload_size() const; | |
60 | |
61 size_t num_handles() const { return header_->num_handles; } | |
62 bool has_handles() const { return header_->num_handles > 0; } | |
63 PlatformHandle* handles(); | |
64 | |
65 // Note: SetHandles() and TakeHandles() invalidate any previous value of | |
66 // handles(). | |
67 void SetHandles(ScopedPlatformHandleVectorPtr new_handles); | |
68 ScopedPlatformHandleVectorPtr TakeHandles(); | |
69 | |
70 private: | |
71 size_t size_; | |
72 char* data_; | |
73 Header* header_; | |
74 | |
75 #if defined(OS_WIN) | |
76 // On Windows, handles are serialized in the data buffer along with the | |
77 // rest of the payload. | |
78 PlatformHandle* handles_ = nullptr; | |
79 #else | |
80 ScopedPlatformHandleVectorPtr handle_vector_; | |
81 #endif | |
82 | |
83 DISALLOW_COPY_AND_ASSIGN(Message); | |
84 }; | |
85 | |
86 // Delegate methods are called from the I/O task runner with which the Channel | |
87 // was created (see Channel::Create). | |
88 class Delegate { | |
89 public: | |
90 virtual ~Delegate() {} | |
91 | |
92 // Notify of a received message. |payload| is not owned and must not be | |
93 // retained; it will be null if |payload_size| is 0. |handles| are | |
94 // transferred to the callee. | |
95 virtual void OnChannelMessage(const void* payload, | |
96 size_t payload_size, | |
97 ScopedPlatformHandleVectorPtr handles) = 0; | |
98 | |
99 // Notify that an error has occured and the Channel will cease operation. | |
100 virtual void OnChannelError() = 0; | |
101 }; | |
102 | |
103 // Creates a new Channel around a |platform_handle|, taking ownership of the | |
104 // handle. All I/O on the handle will be performed on |io_task_runner|. | |
105 // Note that ShutDown() MUST be called on the Channel some time before | |
106 // |delegate| is destroyed. | |
107 static scoped_refptr<Channel> Create( | |
108 Delegate* delegate, | |
109 ScopedPlatformHandle platform_handle, | |
110 scoped_refptr<base::TaskRunner> io_task_runner); | |
111 | |
112 // Request that the channel be shut down. This should always be called before | |
113 // releasing the last reference to a Channel to ensure that it's cleaned up | |
114 // on its I/O task runner's thread. | |
115 // | |
116 // Delegate methods will no longer be invoked after this call. | |
117 void ShutDown(); | |
Anand Mistry (off Chromium)
2016/01/28 02:26:24
It's not clear which threads these can be called o
| |
118 | |
119 // Begin processing I/O events. Delegate methods must only be invoked after | |
120 // this call. | |
121 virtual void Start() = 0; | |
122 | |
123 // Stop processing I/O events. | |
124 virtual void ShutDownImpl() = 0; | |
125 | |
126 // Queues an outgoing message on the Channel. This message will either | |
127 // eventually be written or will fail to write and trigger | |
128 // Delegate::OnChannelError. | |
129 virtual void Write(MessagePtr message) = 0; | |
130 | |
131 protected: | |
132 explicit Channel(Delegate* delegate); | |
133 virtual ~Channel(); | |
134 | |
135 // Called by the implementation when it wants somewhere to stick data. | |
136 // |*buffer_capacity| may be set by the caller to indicate the desired buffer | |
137 // size. If 0, a sane default size will be used instead. | |
138 // | |
139 // Returns the address of a buffer which can be written to, and indicates its | |
140 // actual capacity in |*buffer_capacity|. | |
141 char* GetReadBuffer(size_t* buffer_capacity); | |
142 | |
143 // Called by the implementation when new data is available in the read | |
144 // buffer. Returns false to indicate an error. Upon success, | |
145 // |*next_read_size_hint| will be set to a recommended size for the next | |
146 // read done by the implementation. | |
147 bool OnReadComplete(size_t bytes_read, size_t* next_read_size_hint); | |
148 | |
149 // Called by the implementation when something goes horribly wrong. It is NOT | |
150 // OK to call this synchronously from any public interface methods. | |
151 void OnError(); | |
152 | |
153 // Retrieves the set of platform handles read for a given message. |payload| | |
154 // and |payload_size| correspond to the full message body. Depending on | |
155 // the Channel implementation, this body may encode platform handles, or | |
156 // handles may be stored and managed elsewhere by the implementation. | |
157 // If |num_handles| handles cannot be returned, this must return null. | |
158 // The implementation may also adjust the values of |*payload| and/or | |
159 // |*payload_size| to hide handle data from the user. | |
160 virtual ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | |
161 size_t num_handles, | |
162 void** payload, | |
163 size_t* payload_size) = 0; | |
164 | |
165 private: | |
166 friend class base::RefCountedThreadSafe<Channel>; | |
167 | |
168 class ReadBuffer; | |
169 | |
170 Delegate* delegate_; | |
171 const scoped_ptr<ReadBuffer> read_buffer_; | |
172 | |
173 DISALLOW_COPY_AND_ASSIGN(Channel); | |
174 }; | |
175 | |
176 } // namespace edk | |
177 } // namespace mojo | |
178 | |
179 #endif // MOJO_EDK_SYSTEM_CHANNEL_H_ | |
OLD | NEW |