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

Side by Side Diff: mojo/edk/system/dispatcher.cc

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move to mojo::edk namespace in preparation for runtim flag Created 5 years, 2 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/edk/system/dispatcher.h" 5 #include "mojo/edk/system/dispatcher.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "mojo/edk/system/configuration.h" 8 #include "mojo/edk/system/configuration.h"
9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" 9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h"
10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" 10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h"
11 #include "mojo/edk/system/message_pipe_dispatcher.h" 11 #include "mojo/edk/system/message_pipe_dispatcher.h"
12 #include "mojo/edk/system/platform_handle_dispatcher.h" 12 #include "mojo/edk/system/platform_handle_dispatcher.h"
13 #include "mojo/edk/system/shared_buffer_dispatcher.h" 13 #include "mojo/edk/system/shared_buffer_dispatcher.h"
14 14
15 namespace mojo { 15 namespace mojo {
16 namespace system { 16 namespace edk {
17 17
18 namespace test { 18 namespace test {
19 19
20 // TODO(vtl): Maybe this should be defined in a test-only file instead. 20 // TODO(vtl): Maybe this should be defined in a test-only file instead.
21 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) { 21 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) {
22 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher); 22 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
23 } 23 }
24 24
25 } // namespace test 25 } // namespace test
26 26
27 // Dispatcher ------------------------------------------------------------------ 27 // Dispatcher ------------------------------------------------------------------
28 28
29 // TODO(vtl): The thread-safety analyzer isn't smart enough to deal with the
30 // fact that we give up if |TryLock()| fails.
31 // static 29 // static
32 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport( 30 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
33 Dispatcher* dispatcher) MOJO_NO_THREAD_SAFETY_ANALYSIS { 31 Dispatcher* dispatcher) {
34 DCHECK(dispatcher); 32 DCHECK(dispatcher);
35 33
36 if (!dispatcher->mutex_.TryLock()) 34 // if (!dispatcher->lock_.Try())
37 return DispatcherTransport(); 35 // return DispatcherTransport();
36 // Our dispatcher implemetnations hop to IO thread on initialization, so it's
37 // valid that while their raw channel os being initialized on IO thread, the
38 // dispatcher is being sent. We handle this by just acquiring the lock.
39
40 // See comment in header for why we need this.
41 dispatcher->TransportStarted();
42
43 dispatcher->lock_.Acquire();
38 44
39 // We shouldn't race with things that close dispatchers, since closing can 45 // We shouldn't race with things that close dispatchers, since closing can
40 // only take place either under |handle_table_mutex_| or when the handle is 46 // only take place either under |handle_table_lock_| or when the handle is
41 // marked as busy. 47 // marked as busy.
42 DCHECK(!dispatcher->is_closed_); 48 DCHECK(!dispatcher->is_closed_);
43 49
44 return DispatcherTransport(dispatcher); 50 return DispatcherTransport(dispatcher);
45 } 51 }
46 52
47 // static 53 // static
48 void Dispatcher::TransportDataAccess::StartSerialize( 54 void Dispatcher::TransportDataAccess::StartSerialize(
49 Dispatcher* dispatcher, 55 Dispatcher* dispatcher,
50 Channel* channel,
51 size_t* max_size, 56 size_t* max_size,
52 size_t* max_platform_handles) { 57 size_t* max_platform_handles) {
53 DCHECK(dispatcher); 58 DCHECK(dispatcher);
54 dispatcher->StartSerialize(channel, max_size, max_platform_handles); 59 dispatcher->StartSerialize(max_size, max_platform_handles);
55 } 60 }
56 61
57 // static 62 // static
58 bool Dispatcher::TransportDataAccess::EndSerializeAndClose( 63 bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
59 Dispatcher* dispatcher, 64 Dispatcher* dispatcher,
60 Channel* channel,
61 void* destination, 65 void* destination,
62 size_t* actual_size, 66 size_t* actual_size,
63 embedder::PlatformHandleVector* platform_handles) { 67 PlatformHandleVector* platform_handles) {
64 DCHECK(dispatcher); 68 DCHECK(dispatcher);
65 return dispatcher->EndSerializeAndClose(channel, destination, actual_size, 69 return dispatcher->EndSerializeAndClose(destination, actual_size,
66 platform_handles); 70 platform_handles);
67 } 71 }
68 72
69 // static 73 // static
70 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( 74 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
71 Channel* channel,
72 int32_t type, 75 int32_t type,
73 const void* source, 76 const void* source,
74 size_t size, 77 size_t size,
75 embedder::PlatformHandleVector* platform_handles) { 78 PlatformHandleVector* platform_handles) {
76 switch (static_cast<Dispatcher::Type>(type)) { 79 switch (static_cast<Dispatcher::Type>(type)) {
77 case Type::UNKNOWN: 80 case Type::UNKNOWN:
78 DVLOG(2) << "Deserializing invalid handle"; 81 DVLOG(2) << "Deserializing invalid handle";
79 return nullptr; 82 return nullptr;
80 case Type::MESSAGE_PIPE: 83 case Type::MESSAGE_PIPE:
81 return scoped_refptr<Dispatcher>( 84 return scoped_refptr<Dispatcher>(MessagePipeDispatcher::Deserialize(
82 MessagePipeDispatcher::Deserialize(channel, source, size)); 85 source, size, platform_handles));
83 case Type::DATA_PIPE_PRODUCER: 86 case Type::DATA_PIPE_PRODUCER:
84 return scoped_refptr<Dispatcher>( 87 return scoped_refptr<Dispatcher>(
85 DataPipeProducerDispatcher::Deserialize(channel, source, size)); 88 DataPipeProducerDispatcher::Deserialize(
89 source, size, platform_handles));
86 case Type::DATA_PIPE_CONSUMER: 90 case Type::DATA_PIPE_CONSUMER:
87 return scoped_refptr<Dispatcher>( 91 return scoped_refptr<Dispatcher>(
88 DataPipeConsumerDispatcher::Deserialize(channel, source, size)); 92 DataPipeConsumerDispatcher::Deserialize(
93 source, size, platform_handles));
89 case Type::SHARED_BUFFER: 94 case Type::SHARED_BUFFER:
90 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize( 95 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
91 channel, source, size, platform_handles)); 96 source, size, platform_handles));
92 case Type::PLATFORM_HANDLE: 97 case Type::PLATFORM_HANDLE:
93 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize( 98 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize(
94 channel, source, size, platform_handles)); 99 source, size, platform_handles));
95 } 100 }
96 LOG(WARNING) << "Unknown dispatcher type " << type; 101 LOG(WARNING) << "Unknown dispatcher type " << type;
97 return nullptr; 102 return nullptr;
98 } 103 }
99 104
100 MojoResult Dispatcher::Close() { 105 MojoResult Dispatcher::Close() {
101 MutexLocker locker(&mutex_); 106 base::AutoLock locker(lock_);
102 if (is_closed_) 107 if (is_closed_)
103 return MOJO_RESULT_INVALID_ARGUMENT; 108 return MOJO_RESULT_INVALID_ARGUMENT;
104 109
105 CloseNoLock(); 110 CloseNoLock();
106 return MOJO_RESULT_OK; 111 return MOJO_RESULT_OK;
107 } 112 }
108 113
109 MojoResult Dispatcher::WriteMessage( 114 MojoResult Dispatcher::WriteMessage(
110 UserPointer<const void> bytes, 115 UserPointer<const void> bytes,
111 uint32_t num_bytes, 116 uint32_t num_bytes,
112 std::vector<DispatcherTransport>* transports, 117 std::vector<DispatcherTransport>* transports,
113 MojoWriteMessageFlags flags) { 118 MojoWriteMessageFlags flags) {
114 DCHECK(!transports || 119 DCHECK(!transports ||
115 (transports->size() > 0 && 120 (transports->size() > 0 &&
116 transports->size() < GetConfiguration().max_message_num_handles)); 121 transports->size() < GetConfiguration().max_message_num_handles));
117 122
118 MutexLocker locker(&mutex_); 123 base::AutoLock locker(lock_);
119 if (is_closed_) 124 if (is_closed_)
120 return MOJO_RESULT_INVALID_ARGUMENT; 125 return MOJO_RESULT_INVALID_ARGUMENT;
121 126
122 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags); 127 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
123 } 128 }
124 129
125 MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes, 130 MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
126 UserPointer<uint32_t> num_bytes, 131 UserPointer<uint32_t> num_bytes,
127 DispatcherVector* dispatchers, 132 DispatcherVector* dispatchers,
128 uint32_t* num_dispatchers, 133 uint32_t* num_dispatchers,
129 MojoReadMessageFlags flags) { 134 MojoReadMessageFlags flags) {
130 DCHECK(!num_dispatchers || *num_dispatchers == 0 || 135 DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
131 (dispatchers && dispatchers->empty())); 136 (dispatchers && dispatchers->empty()));
132 137
133 MutexLocker locker(&mutex_); 138 base::AutoLock locker(lock_);
134 if (is_closed_) 139 if (is_closed_)
135 return MOJO_RESULT_INVALID_ARGUMENT; 140 return MOJO_RESULT_INVALID_ARGUMENT;
136 141
137 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers, 142 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
138 flags); 143 flags);
139 } 144 }
140 145
141 MojoResult Dispatcher::WriteData(UserPointer<const void> elements, 146 MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
142 UserPointer<uint32_t> num_bytes, 147 UserPointer<uint32_t> num_bytes,
143 MojoWriteDataFlags flags) { 148 MojoWriteDataFlags flags) {
144 MutexLocker locker(&mutex_); 149 base::AutoLock locker(lock_);
145 if (is_closed_) 150 if (is_closed_)
146 return MOJO_RESULT_INVALID_ARGUMENT; 151 return MOJO_RESULT_INVALID_ARGUMENT;
147 152
148 return WriteDataImplNoLock(elements, num_bytes, flags); 153 return WriteDataImplNoLock(elements, num_bytes, flags);
149 } 154 }
150 155
151 MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer, 156 MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer,
152 UserPointer<uint32_t> buffer_num_bytes, 157 UserPointer<uint32_t> buffer_num_bytes,
153 MojoWriteDataFlags flags) { 158 MojoWriteDataFlags flags) {
154 MutexLocker locker(&mutex_); 159 base::AutoLock locker(lock_);
155 if (is_closed_) 160 if (is_closed_)
156 return MOJO_RESULT_INVALID_ARGUMENT; 161 return MOJO_RESULT_INVALID_ARGUMENT;
157 162
158 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags); 163 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
159 } 164 }
160 165
161 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { 166 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
162 MutexLocker locker(&mutex_); 167 base::AutoLock locker(lock_);
163 if (is_closed_) 168 if (is_closed_)
164 return MOJO_RESULT_INVALID_ARGUMENT; 169 return MOJO_RESULT_INVALID_ARGUMENT;
165 170
166 return EndWriteDataImplNoLock(num_bytes_written); 171 return EndWriteDataImplNoLock(num_bytes_written);
167 } 172 }
168 173
169 MojoResult Dispatcher::ReadData(UserPointer<void> elements, 174 MojoResult Dispatcher::ReadData(UserPointer<void> elements,
170 UserPointer<uint32_t> num_bytes, 175 UserPointer<uint32_t> num_bytes,
171 MojoReadDataFlags flags) { 176 MojoReadDataFlags flags) {
172 MutexLocker locker(&mutex_); 177 base::AutoLock locker(lock_);
173 if (is_closed_) 178 if (is_closed_)
174 return MOJO_RESULT_INVALID_ARGUMENT; 179 return MOJO_RESULT_INVALID_ARGUMENT;
175 180
176 return ReadDataImplNoLock(elements, num_bytes, flags); 181 return ReadDataImplNoLock(elements, num_bytes, flags);
177 } 182 }
178 183
179 MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer, 184 MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer,
180 UserPointer<uint32_t> buffer_num_bytes, 185 UserPointer<uint32_t> buffer_num_bytes,
181 MojoReadDataFlags flags) { 186 MojoReadDataFlags flags) {
182 MutexLocker locker(&mutex_); 187 base::AutoLock locker(lock_);
183 if (is_closed_) 188 if (is_closed_)
184 return MOJO_RESULT_INVALID_ARGUMENT; 189 return MOJO_RESULT_INVALID_ARGUMENT;
185 190
186 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags); 191 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
187 } 192 }
188 193
189 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { 194 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
190 MutexLocker locker(&mutex_); 195 base::AutoLock locker(lock_);
191 if (is_closed_) 196 if (is_closed_)
192 return MOJO_RESULT_INVALID_ARGUMENT; 197 return MOJO_RESULT_INVALID_ARGUMENT;
193 198
194 return EndReadDataImplNoLock(num_bytes_read); 199 return EndReadDataImplNoLock(num_bytes_read);
195 } 200 }
196 201
197 MojoResult Dispatcher::DuplicateBufferHandle( 202 MojoResult Dispatcher::DuplicateBufferHandle(
198 UserPointer<const MojoDuplicateBufferHandleOptions> options, 203 UserPointer<const MojoDuplicateBufferHandleOptions> options,
199 scoped_refptr<Dispatcher>* new_dispatcher) { 204 scoped_refptr<Dispatcher>* new_dispatcher) {
200 MutexLocker locker(&mutex_); 205 base::AutoLock locker(lock_);
201 if (is_closed_) 206 if (is_closed_)
202 return MOJO_RESULT_INVALID_ARGUMENT; 207 return MOJO_RESULT_INVALID_ARGUMENT;
203 208
204 return DuplicateBufferHandleImplNoLock(options, new_dispatcher); 209 return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
205 } 210 }
206 211
207 MojoResult Dispatcher::MapBuffer( 212 MojoResult Dispatcher::MapBuffer(
208 uint64_t offset, 213 uint64_t offset,
209 uint64_t num_bytes, 214 uint64_t num_bytes,
210 MojoMapBufferFlags flags, 215 MojoMapBufferFlags flags,
211 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) { 216 scoped_ptr<PlatformSharedBufferMapping>* mapping) {
212 MutexLocker locker(&mutex_); 217 base::AutoLock locker(lock_);
213 if (is_closed_) 218 if (is_closed_)
214 return MOJO_RESULT_INVALID_ARGUMENT; 219 return MOJO_RESULT_INVALID_ARGUMENT;
215 220
216 return MapBufferImplNoLock(offset, num_bytes, flags, mapping); 221 return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
217 } 222 }
218 223
219 HandleSignalsState Dispatcher::GetHandleSignalsState() const { 224 HandleSignalsState Dispatcher::GetHandleSignalsState() const {
220 MutexLocker locker(&mutex_); 225 base::AutoLock locker(lock_);
221 if (is_closed_) 226 if (is_closed_)
222 return HandleSignalsState(); 227 return HandleSignalsState();
223 228
224 return GetHandleSignalsStateImplNoLock(); 229 return GetHandleSignalsStateImplNoLock();
225 } 230 }
226 231
227 MojoResult Dispatcher::AddAwakable(Awakable* awakable, 232 MojoResult Dispatcher::AddAwakable(Awakable* awakable,
228 MojoHandleSignals signals, 233 MojoHandleSignals signals,
229 uint32_t context, 234 uint32_t context,
230 HandleSignalsState* signals_state) { 235 HandleSignalsState* signals_state) {
231 MutexLocker locker(&mutex_); 236 base::AutoLock locker(lock_);
232 if (is_closed_) { 237 if (is_closed_) {
233 if (signals_state) 238 if (signals_state)
234 *signals_state = HandleSignalsState(); 239 *signals_state = HandleSignalsState();
235 return MOJO_RESULT_INVALID_ARGUMENT; 240 return MOJO_RESULT_INVALID_ARGUMENT;
236 } 241 }
237 242
238 return AddAwakableImplNoLock(awakable, signals, context, signals_state); 243 return AddAwakableImplNoLock(awakable, signals, context, signals_state);
239 } 244 }
240 245
241 void Dispatcher::RemoveAwakable(Awakable* awakable, 246 void Dispatcher::RemoveAwakable(Awakable* awakable,
242 HandleSignalsState* handle_signals_state) { 247 HandleSignalsState* handle_signals_state) {
243 MutexLocker locker(&mutex_); 248 base::AutoLock locker(lock_);
244 if (is_closed_) { 249 if (is_closed_) {
245 if (handle_signals_state) 250 if (handle_signals_state)
246 *handle_signals_state = HandleSignalsState(); 251 *handle_signals_state = HandleSignalsState();
247 return; 252 return;
248 } 253 }
249 254
250 RemoveAwakableImplNoLock(awakable, handle_signals_state); 255 RemoveAwakableImplNoLock(awakable, handle_signals_state);
251 } 256 }
252 257
253 Dispatcher::Dispatcher() : is_closed_(false) { 258 Dispatcher::Dispatcher() : is_closed_(false) {
254 } 259 }
255 260
256 Dispatcher::~Dispatcher() { 261 Dispatcher::~Dispatcher() {
257 // Make sure that |Close()| was called. 262 // Make sure that |Close()| was called.
258 DCHECK(is_closed_); 263 DCHECK(is_closed_);
259 } 264 }
260 265
261 void Dispatcher::CancelAllAwakablesNoLock() { 266 void Dispatcher::CancelAllAwakablesNoLock() {
262 mutex_.AssertHeld(); 267 lock_.AssertAcquired();
263 DCHECK(is_closed_); 268 DCHECK(is_closed_);
264 // By default, waiting isn't supported. Only dispatchers that can be waited on 269 // By default, waiting isn't supported. Only dispatchers that can be waited on
265 // will do something nontrivial. 270 // will do something nontrivial.
266 } 271 }
267 272
268 void Dispatcher::CloseImplNoLock() { 273 void Dispatcher::CloseImplNoLock() {
269 mutex_.AssertHeld(); 274 lock_.AssertAcquired();
270 DCHECK(is_closed_); 275 DCHECK(is_closed_);
271 // This may not need to do anything. Dispatchers should override this to do 276 // This may not need to do anything. Dispatchers should override this to do
272 // any actual close-time cleanup necessary. 277 // any actual close-time cleanup necessary.
273 } 278 }
274 279
275 MojoResult Dispatcher::WriteMessageImplNoLock( 280 MojoResult Dispatcher::WriteMessageImplNoLock(
276 UserPointer<const void> /*bytes*/, 281 UserPointer<const void> /*bytes*/,
277 uint32_t /*num_bytes*/, 282 uint32_t /*num_bytes*/,
278 std::vector<DispatcherTransport>* /*transports*/, 283 std::vector<DispatcherTransport>* /*transports*/,
279 MojoWriteMessageFlags /*flags*/) { 284 MojoWriteMessageFlags /*flags*/) {
280 mutex_.AssertHeld(); 285 lock_.AssertAcquired();
281 DCHECK(!is_closed_); 286 DCHECK(!is_closed_);
282 // By default, not supported. Only needed for message pipe dispatchers. 287 // By default, not supported. Only needed for message pipe dispatchers.
283 return MOJO_RESULT_INVALID_ARGUMENT; 288 return MOJO_RESULT_INVALID_ARGUMENT;
284 } 289 }
285 290
286 MojoResult Dispatcher::ReadMessageImplNoLock( 291 MojoResult Dispatcher::ReadMessageImplNoLock(
287 UserPointer<void> /*bytes*/, 292 UserPointer<void> /*bytes*/,
288 UserPointer<uint32_t> /*num_bytes*/, 293 UserPointer<uint32_t> /*num_bytes*/,
289 DispatcherVector* /*dispatchers*/, 294 DispatcherVector* /*dispatchers*/,
290 uint32_t* /*num_dispatchers*/, 295 uint32_t* /*num_dispatchers*/,
291 MojoReadMessageFlags /*flags*/) { 296 MojoReadMessageFlags /*flags*/) {
292 mutex_.AssertHeld(); 297 lock_.AssertAcquired();
293 DCHECK(!is_closed_); 298 DCHECK(!is_closed_);
294 // By default, not supported. Only needed for message pipe dispatchers. 299 // By default, not supported. Only needed for message pipe dispatchers.
295 return MOJO_RESULT_INVALID_ARGUMENT; 300 return MOJO_RESULT_INVALID_ARGUMENT;
296 } 301 }
297 302
298 MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/, 303 MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
299 UserPointer<uint32_t> /*num_bytes*/, 304 UserPointer<uint32_t> /*num_bytes*/,
300 MojoWriteDataFlags /*flags*/) { 305 MojoWriteDataFlags /*flags*/) {
301 mutex_.AssertHeld(); 306 lock_.AssertAcquired();
302 DCHECK(!is_closed_); 307 DCHECK(!is_closed_);
303 // By default, not supported. Only needed for data pipe dispatchers. 308 // By default, not supported. Only needed for data pipe dispatchers.
304 return MOJO_RESULT_INVALID_ARGUMENT; 309 return MOJO_RESULT_INVALID_ARGUMENT;
305 } 310 }
306 311
307 MojoResult Dispatcher::BeginWriteDataImplNoLock( 312 MojoResult Dispatcher::BeginWriteDataImplNoLock(
308 UserPointer<void*> /*buffer*/, 313 UserPointer<void*> /*buffer*/,
309 UserPointer<uint32_t> /*buffer_num_bytes*/, 314 UserPointer<uint32_t> /*buffer_num_bytes*/,
310 MojoWriteDataFlags /*flags*/) { 315 MojoWriteDataFlags /*flags*/) {
311 mutex_.AssertHeld(); 316 lock_.AssertAcquired();
312 DCHECK(!is_closed_); 317 DCHECK(!is_closed_);
313 // By default, not supported. Only needed for data pipe dispatchers. 318 // By default, not supported. Only needed for data pipe dispatchers.
314 return MOJO_RESULT_INVALID_ARGUMENT; 319 return MOJO_RESULT_INVALID_ARGUMENT;
315 } 320 }
316 321
317 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) { 322 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
318 mutex_.AssertHeld(); 323 lock_.AssertAcquired();
319 DCHECK(!is_closed_); 324 DCHECK(!is_closed_);
320 // By default, not supported. Only needed for data pipe dispatchers. 325 // By default, not supported. Only needed for data pipe dispatchers.
321 return MOJO_RESULT_INVALID_ARGUMENT; 326 return MOJO_RESULT_INVALID_ARGUMENT;
322 } 327 }
323 328
324 MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/, 329 MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/,
325 UserPointer<uint32_t> /*num_bytes*/, 330 UserPointer<uint32_t> /*num_bytes*/,
326 MojoReadDataFlags /*flags*/) { 331 MojoReadDataFlags /*flags*/) {
327 mutex_.AssertHeld(); 332 lock_.AssertAcquired();
328 DCHECK(!is_closed_); 333 DCHECK(!is_closed_);
329 // By default, not supported. Only needed for data pipe dispatchers. 334 // By default, not supported. Only needed for data pipe dispatchers.
330 return MOJO_RESULT_INVALID_ARGUMENT; 335 return MOJO_RESULT_INVALID_ARGUMENT;
331 } 336 }
332 337
333 MojoResult Dispatcher::BeginReadDataImplNoLock( 338 MojoResult Dispatcher::BeginReadDataImplNoLock(
334 UserPointer<const void*> /*buffer*/, 339 UserPointer<const void*> /*buffer*/,
335 UserPointer<uint32_t> /*buffer_num_bytes*/, 340 UserPointer<uint32_t> /*buffer_num_bytes*/,
336 MojoReadDataFlags /*flags*/) { 341 MojoReadDataFlags /*flags*/) {
337 mutex_.AssertHeld(); 342 lock_.AssertAcquired();
338 DCHECK(!is_closed_); 343 DCHECK(!is_closed_);
339 // By default, not supported. Only needed for data pipe dispatchers. 344 // By default, not supported. Only needed for data pipe dispatchers.
340 return MOJO_RESULT_INVALID_ARGUMENT; 345 return MOJO_RESULT_INVALID_ARGUMENT;
341 } 346 }
342 347
343 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { 348 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
344 mutex_.AssertHeld(); 349 lock_.AssertAcquired();
345 DCHECK(!is_closed_); 350 DCHECK(!is_closed_);
346 // By default, not supported. Only needed for data pipe dispatchers. 351 // By default, not supported. Only needed for data pipe dispatchers.
347 return MOJO_RESULT_INVALID_ARGUMENT; 352 return MOJO_RESULT_INVALID_ARGUMENT;
348 } 353 }
349 354
350 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( 355 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
351 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/, 356 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/,
352 scoped_refptr<Dispatcher>* /*new_dispatcher*/) { 357 scoped_refptr<Dispatcher>* /*new_dispatcher*/) {
353 mutex_.AssertHeld(); 358 lock_.AssertAcquired();
354 DCHECK(!is_closed_); 359 DCHECK(!is_closed_);
355 // By default, not supported. Only needed for buffer dispatchers. 360 // By default, not supported. Only needed for buffer dispatchers.
356 return MOJO_RESULT_INVALID_ARGUMENT; 361 return MOJO_RESULT_INVALID_ARGUMENT;
357 } 362 }
358 363
359 MojoResult Dispatcher::MapBufferImplNoLock( 364 MojoResult Dispatcher::MapBufferImplNoLock(
360 uint64_t /*offset*/, 365 uint64_t /*offset*/,
361 uint64_t /*num_bytes*/, 366 uint64_t /*num_bytes*/,
362 MojoMapBufferFlags /*flags*/, 367 MojoMapBufferFlags /*flags*/,
363 scoped_ptr<embedder::PlatformSharedBufferMapping>* /*mapping*/) { 368 scoped_ptr<PlatformSharedBufferMapping>* /*mapping*/) {
364 mutex_.AssertHeld(); 369 lock_.AssertAcquired();
365 DCHECK(!is_closed_); 370 DCHECK(!is_closed_);
366 // By default, not supported. Only needed for buffer dispatchers. 371 // By default, not supported. Only needed for buffer dispatchers.
367 return MOJO_RESULT_INVALID_ARGUMENT; 372 return MOJO_RESULT_INVALID_ARGUMENT;
368 } 373 }
369 374
370 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const { 375 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const {
371 mutex_.AssertHeld(); 376 lock_.AssertAcquired();
372 DCHECK(!is_closed_); 377 DCHECK(!is_closed_);
373 // By default, waiting isn't supported. Only dispatchers that can be waited on 378 // By default, waiting isn't supported. Only dispatchers that can be waited on
374 // will do something nontrivial. 379 // will do something nontrivial.
375 return HandleSignalsState(); 380 return HandleSignalsState();
376 } 381 }
377 382
378 MojoResult Dispatcher::AddAwakableImplNoLock( 383 MojoResult Dispatcher::AddAwakableImplNoLock(
379 Awakable* /*awakable*/, 384 Awakable* /*awakable*/,
380 MojoHandleSignals /*signals*/, 385 MojoHandleSignals /*signals*/,
381 uint32_t /*context*/, 386 uint32_t /*context*/,
382 HandleSignalsState* signals_state) { 387 HandleSignalsState* signals_state) {
383 mutex_.AssertHeld(); 388 lock_.AssertAcquired();
384 DCHECK(!is_closed_); 389 DCHECK(!is_closed_);
385 // By default, waiting isn't supported. Only dispatchers that can be waited on 390 // By default, waiting isn't supported. Only dispatchers that can be waited on
386 // will do something nontrivial. 391 // will do something nontrivial.
387 if (signals_state) 392 if (signals_state)
388 *signals_state = HandleSignalsState(); 393 *signals_state = HandleSignalsState();
389 return MOJO_RESULT_FAILED_PRECONDITION; 394 return MOJO_RESULT_FAILED_PRECONDITION;
390 } 395 }
391 396
392 void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/, 397 void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/,
393 HandleSignalsState* signals_state) { 398 HandleSignalsState* signals_state) {
394 mutex_.AssertHeld(); 399 lock_.AssertAcquired();
395 DCHECK(!is_closed_); 400 DCHECK(!is_closed_);
396 // By default, waiting isn't supported. Only dispatchers that can be waited on 401 // By default, waiting isn't supported. Only dispatchers that can be waited on
397 // will do something nontrivial. 402 // will do something nontrivial.
398 if (signals_state) 403 if (signals_state)
399 *signals_state = HandleSignalsState(); 404 *signals_state = HandleSignalsState();
400 } 405 }
401 406
402 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, 407 void Dispatcher::StartSerializeImplNoLock(size_t* max_size,
403 size_t* max_size,
404 size_t* max_platform_handles) { 408 size_t* max_platform_handles) {
405 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 409 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
406 DCHECK(!is_closed_); 410 DCHECK(!is_closed_);
407 *max_size = 0; 411 *max_size = 0;
408 *max_platform_handles = 0; 412 *max_platform_handles = 0;
409 } 413 }
410 414
411 bool Dispatcher::EndSerializeAndCloseImplNoLock( 415 bool Dispatcher::EndSerializeAndCloseImplNoLock(
412 Channel* /*channel*/,
413 void* /*destination*/, 416 void* /*destination*/,
414 size_t* /*actual_size*/, 417 size_t* /*actual_size*/,
415 embedder::PlatformHandleVector* /*platform_handles*/) { 418 PlatformHandleVector* /*platform_handles*/) {
416 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 419 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
417 DCHECK(is_closed_); 420 DCHECK(is_closed_);
418 // By default, serializing isn't supported, so just close. 421 // By default, serializing isn't supported, so just close.
419 CloseImplNoLock(); 422 CloseImplNoLock();
420 return false; 423 return false;
421 } 424 }
422 425
423 bool Dispatcher::IsBusyNoLock() const { 426 bool Dispatcher::IsBusyNoLock() const {
424 mutex_.AssertHeld(); 427 lock_.AssertAcquired();
425 DCHECK(!is_closed_); 428 DCHECK(!is_closed_);
426 // Most dispatchers support only "atomic" operations, so they are never busy 429 // Most dispatchers support only "atomic" operations, so they are never busy
427 // (in this sense). 430 // (in this sense).
428 return false; 431 return false;
429 } 432 }
430 433
431 void Dispatcher::CloseNoLock() { 434 void Dispatcher::CloseNoLock() {
432 mutex_.AssertHeld(); 435 lock_.AssertAcquired();
433 DCHECK(!is_closed_); 436 DCHECK(!is_closed_);
434 437
435 is_closed_ = true; 438 is_closed_ = true;
436 CancelAllAwakablesNoLock(); 439 CancelAllAwakablesNoLock();
437 CloseImplNoLock(); 440 CloseImplNoLock();
438 } 441 }
439 442
440 scoped_refptr<Dispatcher> 443 scoped_refptr<Dispatcher>
441 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { 444 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
442 mutex_.AssertHeld(); 445 lock_.AssertAcquired();
443 DCHECK(!is_closed_); 446 DCHECK(!is_closed_);
444 447
445 is_closed_ = true; 448 is_closed_ = true;
446 CancelAllAwakablesNoLock(); 449 CancelAllAwakablesNoLock();
447 return CreateEquivalentDispatcherAndCloseImplNoLock(); 450 return CreateEquivalentDispatcherAndCloseImplNoLock();
448 } 451 }
449 452
450 void Dispatcher::StartSerialize(Channel* channel, 453 void Dispatcher::StartSerialize(size_t* max_size,
451 size_t* max_size,
452 size_t* max_platform_handles) { 454 size_t* max_platform_handles) {
453 DCHECK(channel);
454 DCHECK(max_size); 455 DCHECK(max_size);
455 DCHECK(max_platform_handles); 456 DCHECK(max_platform_handles);
456 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 457 //DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
458 // jam: document exactly when this happens: i.e. when startserialize is called
459 // on main thread.
457 DCHECK(!is_closed_); 460 DCHECK(!is_closed_);
458 StartSerializeImplNoLock(channel, max_size, max_platform_handles); 461 StartSerializeImplNoLock(max_size, max_platform_handles);
459 } 462 }
460 463
461 bool Dispatcher::EndSerializeAndClose( 464 bool Dispatcher::EndSerializeAndClose(void* destination,
462 Channel* channel, 465 size_t* actual_size,
463 void* destination, 466 PlatformHandleVector* platform_handles) {
464 size_t* actual_size,
465 embedder::PlatformHandleVector* platform_handles) {
466 DCHECK(channel);
467 DCHECK(actual_size); 467 DCHECK(actual_size);
468 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 468 //DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
469 // jam: same as startserialize
469 DCHECK(!is_closed_); 470 DCHECK(!is_closed_);
470 471
471 // Like other |...Close()| methods, we mark ourselves as closed before calling 472 // Like other |...Close()| methods, we mark ourselves as closed before calling
472 // the impl. But there's no need to cancel waiters: we shouldn't have any (and 473 // the impl. But there's no need to cancel waiters: we shouldn't have any (and
473 // shouldn't be in |Core|'s handle table. 474 // shouldn't be in |Core|'s handle table.
474 is_closed_ = true; 475 is_closed_ = true;
475 476
476 #if !defined(NDEBUG) 477 #if !defined(NDEBUG)
477 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking 478 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
478 // isn't actually needed, but we need to satisfy assertions (which we don't 479 // isn't actually needed, but we need to satisfy assertions (which we don't
479 // want to remove or weaken). 480 // want to remove or weaken).
480 MutexLocker locker(&mutex_); 481 base::AutoLock locker(lock_);
481 #endif 482 #endif
482 483
483 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size, 484 return EndSerializeAndCloseImplNoLock(destination, actual_size,
484 platform_handles); 485 platform_handles);
485 } 486 }
486 487
487 // DispatcherTransport --------------------------------------------------------- 488 // DispatcherTransport ---------------------------------------------------------
488 489
489 void DispatcherTransport::End() { 490 void DispatcherTransport::End() {
490 DCHECK(dispatcher_); 491 DCHECK(dispatcher_);
491 dispatcher_->mutex_.Unlock(); 492 dispatcher_->lock_.Release();
493
494 dispatcher_->TransportEnded();
495
492 dispatcher_ = nullptr; 496 dispatcher_ = nullptr;
493 } 497 }
494 498
495 } // namespace system 499 } // namespace edk
496 } // namespace mojo 500 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698