OLD | NEW |
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/system/core.h" | 5 #include "mojo/system/core.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "mojo/public/c/system/macros.h" | |
12 #include "mojo/system/constants.h" | 11 #include "mojo/system/constants.h" |
13 #include "mojo/system/data_pipe.h" | 12 #include "mojo/system/data_pipe.h" |
14 #include "mojo/system/data_pipe_consumer_dispatcher.h" | 13 #include "mojo/system/data_pipe_consumer_dispatcher.h" |
15 #include "mojo/system/data_pipe_producer_dispatcher.h" | 14 #include "mojo/system/data_pipe_producer_dispatcher.h" |
16 #include "mojo/system/dispatcher.h" | 15 #include "mojo/system/dispatcher.h" |
17 #include "mojo/system/local_data_pipe.h" | 16 #include "mojo/system/local_data_pipe.h" |
18 #include "mojo/system/memory.h" | 17 #include "mojo/system/memory.h" |
19 #include "mojo/system/message_pipe.h" | 18 #include "mojo/system/message_pipe.h" |
20 #include "mojo/system/message_pipe_dispatcher.h" | 19 #include "mojo/system/message_pipe_dispatcher.h" |
21 #include "mojo/system/raw_shared_buffer.h" | 20 #include "mojo/system/raw_shared_buffer.h" |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 MojoResult Core::Wait(MojoHandle handle, | 119 MojoResult Core::Wait(MojoHandle handle, |
121 MojoWaitFlags flags, | 120 MojoWaitFlags flags, |
122 MojoDeadline deadline) { | 121 MojoDeadline deadline) { |
123 return WaitManyInternal(&handle, &flags, 1, deadline); | 122 return WaitManyInternal(&handle, &flags, 1, deadline); |
124 } | 123 } |
125 | 124 |
126 MojoResult Core::WaitMany(const MojoHandle* handles, | 125 MojoResult Core::WaitMany(const MojoHandle* handles, |
127 const MojoWaitFlags* flags, | 126 const MojoWaitFlags* flags, |
128 uint32_t num_handles, | 127 uint32_t num_handles, |
129 MojoDeadline deadline) { | 128 MojoDeadline deadline) { |
130 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) | 129 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) |
131 return MOJO_RESULT_INVALID_ARGUMENT; | 130 return MOJO_RESULT_INVALID_ARGUMENT; |
132 if (!VerifyUserPointerWithCount<MojoWaitFlags>(flags, num_handles)) | 131 if (!VerifyUserPointer<MojoWaitFlags>(flags, num_handles)) |
133 return MOJO_RESULT_INVALID_ARGUMENT; | 132 return MOJO_RESULT_INVALID_ARGUMENT; |
134 if (num_handles < 1) | 133 if (num_handles < 1) |
135 return MOJO_RESULT_INVALID_ARGUMENT; | 134 return MOJO_RESULT_INVALID_ARGUMENT; |
136 if (num_handles > kMaxWaitManyNumHandles) | 135 if (num_handles > kMaxWaitManyNumHandles) |
137 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 136 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
138 return WaitManyInternal(handles, flags, num_handles, deadline); | 137 return WaitManyInternal(handles, flags, num_handles, deadline); |
139 } | 138 } |
140 | 139 |
141 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0, | 140 MojoResult Core::CreateMessagePipe(MojoHandle* message_pipe_handle0, |
142 MojoHandle* message_pipe_handle1) { | 141 MojoHandle* message_pipe_handle1) { |
143 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0)) | 142 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle0, 1)) |
144 return MOJO_RESULT_INVALID_ARGUMENT; | 143 return MOJO_RESULT_INVALID_ARGUMENT; |
145 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1)) | 144 if (!VerifyUserPointer<MojoHandle>(message_pipe_handle1, 1)) |
146 return MOJO_RESULT_INVALID_ARGUMENT; | 145 return MOJO_RESULT_INVALID_ARGUMENT; |
147 | 146 |
148 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher()); | 147 scoped_refptr<MessagePipeDispatcher> dispatcher0(new MessagePipeDispatcher()); |
149 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher()); | 148 scoped_refptr<MessagePipeDispatcher> dispatcher1(new MessagePipeDispatcher()); |
150 | 149 |
151 std::pair<MojoHandle, MojoHandle> handle_pair; | 150 std::pair<MojoHandle, MojoHandle> handle_pair; |
152 { | 151 { |
153 base::AutoLock locker(handle_table_lock_); | 152 base::AutoLock locker(handle_table_lock_); |
154 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); | 153 handle_pair = handle_table_.AddDispatcherPair(dispatcher0, dispatcher1); |
155 } | 154 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); | 191 return dispatcher->WriteMessage(bytes, num_bytes, NULL, flags); |
193 | 192 |
194 // We have to handle |handles| here, since we have to mark them busy in the | 193 // We have to handle |handles| here, since we have to mark them busy in the |
195 // global handle table. We can't delegate this to the dispatcher, since the | 194 // global handle table. We can't delegate this to the dispatcher, since the |
196 // handle table lock must be acquired before the dispatcher lock. | 195 // handle table lock must be acquired before the dispatcher lock. |
197 // | 196 // |
198 // (This leads to an oddity: |handles|/|num_handles| are always verified for | 197 // (This leads to an oddity: |handles|/|num_handles| are always verified for |
199 // validity, even for dispatchers that don't support |WriteMessage()| and will | 198 // validity, even for dispatchers that don't support |WriteMessage()| and will |
200 // simply return failure unconditionally. It also breaks the usual | 199 // simply return failure unconditionally. It also breaks the usual |
201 // left-to-right verification order of arguments.) | 200 // left-to-right verification order of arguments.) |
202 if (!VerifyUserPointerWithCount<MojoHandle>(handles, num_handles)) | 201 if (!VerifyUserPointer<MojoHandle>(handles, num_handles)) |
203 return MOJO_RESULT_INVALID_ARGUMENT; | 202 return MOJO_RESULT_INVALID_ARGUMENT; |
204 if (num_handles > kMaxMessageNumHandles) | 203 if (num_handles > kMaxMessageNumHandles) |
205 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 204 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
206 | 205 |
207 // We'll need to hold on to the dispatchers so that we can pass them on to | 206 // We'll need to hold on to the dispatchers so that we can pass them on to |
208 // |WriteMessage()| and also so that we can unlock their locks afterwards | 207 // |WriteMessage()| and also so that we can unlock their locks afterwards |
209 // without accessing the handle table. These can be dumb pointers, since their | 208 // without accessing the handle table. These can be dumb pointers, since their |
210 // entries in the handle table won't get removed (since they'll be marked as | 209 // entries in the handle table won't get removed (since they'll be marked as |
211 // busy). | 210 // busy). |
212 std::vector<DispatcherTransport> transports(num_handles); | 211 std::vector<DispatcherTransport> transports(num_handles); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 void* bytes, | 244 void* bytes, |
246 uint32_t* num_bytes, | 245 uint32_t* num_bytes, |
247 MojoHandle* handles, | 246 MojoHandle* handles, |
248 uint32_t* num_handles, | 247 uint32_t* num_handles, |
249 MojoReadMessageFlags flags) { | 248 MojoReadMessageFlags flags) { |
250 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); | 249 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); |
251 if (!dispatcher) | 250 if (!dispatcher) |
252 return MOJO_RESULT_INVALID_ARGUMENT; | 251 return MOJO_RESULT_INVALID_ARGUMENT; |
253 | 252 |
254 if (num_handles) { | 253 if (num_handles) { |
255 if (!VerifyUserPointer<uint32_t>(num_handles)) | 254 if (!VerifyUserPointer<uint32_t>(num_handles, 1)) |
256 return MOJO_RESULT_INVALID_ARGUMENT; | 255 return MOJO_RESULT_INVALID_ARGUMENT; |
257 if (!VerifyUserPointerWithCount<MojoHandle>(handles, *num_handles)) | 256 if (!VerifyUserPointer<MojoHandle>(handles, *num_handles)) |
258 return MOJO_RESULT_INVALID_ARGUMENT; | 257 return MOJO_RESULT_INVALID_ARGUMENT; |
259 } | 258 } |
260 | 259 |
261 // Easy case: won't receive any handles. | 260 // Easy case: won't receive any handles. |
262 if (!num_handles || *num_handles == 0) | 261 if (!num_handles || *num_handles == 0) |
263 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); | 262 return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags); |
264 | 263 |
265 DispatcherVector dispatchers; | 264 DispatcherVector dispatchers; |
266 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, | 265 MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes, |
267 &dispatchers, num_handles, | 266 &dispatchers, num_handles, |
(...skipping 20 matching lines...) Expand all Loading... |
288 } | 287 } |
289 | 288 |
290 return rv; | 289 return rv; |
291 } | 290 } |
292 | 291 |
293 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, | 292 MojoResult Core::CreateDataPipe(const MojoCreateDataPipeOptions* options, |
294 MojoHandle* data_pipe_producer_handle, | 293 MojoHandle* data_pipe_producer_handle, |
295 MojoHandle* data_pipe_consumer_handle) { | 294 MojoHandle* data_pipe_consumer_handle) { |
296 if (options) { | 295 if (options) { |
297 // The |struct_size| field must be valid to read. | 296 // The |struct_size| field must be valid to read. |
298 if (!VerifyUserPointer<uint32_t>(&options->struct_size)) | 297 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) |
299 return MOJO_RESULT_INVALID_ARGUMENT; | 298 return MOJO_RESULT_INVALID_ARGUMENT; |
300 // And then |options| must point to at least |options->struct_size| bytes. | 299 // And then |options| must point to at least |options->struct_size| bytes. |
301 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options, | 300 if (!VerifyUserPointer<void>(options, options->struct_size)) |
302 options->struct_size)) | |
303 return MOJO_RESULT_INVALID_ARGUMENT; | 301 return MOJO_RESULT_INVALID_ARGUMENT; |
304 } | 302 } |
305 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle)) | 303 if (!VerifyUserPointer<MojoHandle>(data_pipe_producer_handle, 1)) |
306 return MOJO_RESULT_INVALID_ARGUMENT; | 304 return MOJO_RESULT_INVALID_ARGUMENT; |
307 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle)) | 305 if (!VerifyUserPointer<MojoHandle>(data_pipe_consumer_handle, 1)) |
308 return MOJO_RESULT_INVALID_ARGUMENT; | 306 return MOJO_RESULT_INVALID_ARGUMENT; |
309 | 307 |
310 MojoCreateDataPipeOptions validated_options = { 0 }; | 308 MojoCreateDataPipeOptions validated_options = { 0 }; |
311 MojoResult result = DataPipe::ValidateOptions(options, &validated_options); | 309 MojoResult result = DataPipe::ValidateOptions(options, &validated_options); |
312 if (result != MOJO_RESULT_OK) | 310 if (result != MOJO_RESULT_OK) |
313 return result; | 311 return result; |
314 | 312 |
315 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( | 313 scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher( |
316 new DataPipeProducerDispatcher()); | 314 new DataPipeProducerDispatcher()); |
317 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( | 315 scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher( |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 | 406 |
409 return dispatcher->EndReadData(num_bytes_read); | 407 return dispatcher->EndReadData(num_bytes_read); |
410 } | 408 } |
411 | 409 |
412 MojoResult Core::CreateSharedBuffer( | 410 MojoResult Core::CreateSharedBuffer( |
413 const MojoCreateSharedBufferOptions* options, | 411 const MojoCreateSharedBufferOptions* options, |
414 uint64_t num_bytes, | 412 uint64_t num_bytes, |
415 MojoHandle* shared_buffer_handle) { | 413 MojoHandle* shared_buffer_handle) { |
416 if (options) { | 414 if (options) { |
417 // The |struct_size| field must be valid to read. | 415 // The |struct_size| field must be valid to read. |
418 if (!VerifyUserPointer<uint32_t>(&options->struct_size)) | 416 if (!VerifyUserPointer<uint32_t>(&options->struct_size, 1)) |
419 return MOJO_RESULT_INVALID_ARGUMENT; | 417 return MOJO_RESULT_INVALID_ARGUMENT; |
420 // And then |options| must point to at least |options->struct_size| bytes. | 418 // And then |options| must point to at least |options->struct_size| bytes. |
421 if (!VerifyUserPointerWithSize<MOJO_ALIGNOF(int64_t)>(options, | 419 if (!VerifyUserPointer<void>(options, options->struct_size)) |
422 options->struct_size)) | |
423 return MOJO_RESULT_INVALID_ARGUMENT; | 420 return MOJO_RESULT_INVALID_ARGUMENT; |
424 } | 421 } |
425 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle)) | 422 if (!VerifyUserPointer<MojoHandle>(shared_buffer_handle, 1)) |
426 return MOJO_RESULT_INVALID_ARGUMENT; | 423 return MOJO_RESULT_INVALID_ARGUMENT; |
427 | 424 |
428 MojoCreateSharedBufferOptions validated_options = { 0 }; | 425 MojoCreateSharedBufferOptions validated_options = { 0 }; |
429 MojoResult result = | 426 MojoResult result = |
430 SharedBufferDispatcher::ValidateOptions(options, &validated_options); | 427 SharedBufferDispatcher::ValidateOptions(options, &validated_options); |
431 if (result != MOJO_RESULT_OK) | 428 if (result != MOJO_RESULT_OK) |
432 return result; | 429 return result; |
433 | 430 |
434 scoped_refptr<SharedBufferDispatcher> dispatcher; | 431 scoped_refptr<SharedBufferDispatcher> dispatcher; |
435 result = SharedBufferDispatcher::Create(validated_options, num_bytes, | 432 result = SharedBufferDispatcher::Create(validated_options, num_bytes, |
(...skipping 16 matching lines...) Expand all Loading... |
452 | 449 |
453 MojoResult Core::DuplicateBufferHandle( | 450 MojoResult Core::DuplicateBufferHandle( |
454 MojoHandle buffer_handle, | 451 MojoHandle buffer_handle, |
455 const MojoDuplicateBufferHandleOptions* options, | 452 const MojoDuplicateBufferHandleOptions* options, |
456 MojoHandle* new_buffer_handle) { | 453 MojoHandle* new_buffer_handle) { |
457 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 454 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
458 if (!dispatcher) | 455 if (!dispatcher) |
459 return MOJO_RESULT_INVALID_ARGUMENT; | 456 return MOJO_RESULT_INVALID_ARGUMENT; |
460 | 457 |
461 // Don't verify |options| here; that's the dispatcher's job. | 458 // Don't verify |options| here; that's the dispatcher's job. |
462 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle)) | 459 if (!VerifyUserPointer<MojoHandle>(new_buffer_handle, 1)) |
463 return MOJO_RESULT_INVALID_ARGUMENT; | 460 return MOJO_RESULT_INVALID_ARGUMENT; |
464 | 461 |
465 scoped_refptr<Dispatcher> new_dispatcher; | 462 scoped_refptr<Dispatcher> new_dispatcher; |
466 MojoResult result = dispatcher->DuplicateBufferHandle(options, | 463 MojoResult result = dispatcher->DuplicateBufferHandle(options, |
467 &new_dispatcher); | 464 &new_dispatcher); |
468 if (result != MOJO_RESULT_OK) | 465 if (result != MOJO_RESULT_OK) |
469 return result; | 466 return result; |
470 | 467 |
471 MojoHandle new_handle = AddDispatcher(new_dispatcher); | 468 MojoHandle new_handle = AddDispatcher(new_dispatcher); |
472 if (new_handle == MOJO_HANDLE_INVALID) { | 469 if (new_handle == MOJO_HANDLE_INVALID) { |
473 LOG(ERROR) << "Handle table full"; | 470 LOG(ERROR) << "Handle table full"; |
474 dispatcher->Close(); | 471 dispatcher->Close(); |
475 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 472 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
476 } | 473 } |
477 | 474 |
478 *new_buffer_handle = new_handle; | 475 *new_buffer_handle = new_handle; |
479 return MOJO_RESULT_OK; | 476 return MOJO_RESULT_OK; |
480 } | 477 } |
481 | 478 |
482 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 479 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
483 uint64_t offset, | 480 uint64_t offset, |
484 uint64_t num_bytes, | 481 uint64_t num_bytes, |
485 void** buffer, | 482 void** buffer, |
486 MojoMapBufferFlags flags) { | 483 MojoMapBufferFlags flags) { |
487 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 484 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
488 if (!dispatcher) | 485 if (!dispatcher) |
489 return MOJO_RESULT_INVALID_ARGUMENT; | 486 return MOJO_RESULT_INVALID_ARGUMENT; |
490 | 487 |
491 if (!VerifyUserPointerWithCount<void*>(buffer, 1)) | 488 if (!VerifyUserPointer<void*>(buffer, 1)) |
492 return MOJO_RESULT_INVALID_ARGUMENT; | 489 return MOJO_RESULT_INVALID_ARGUMENT; |
493 | 490 |
494 scoped_ptr<RawSharedBufferMapping> mapping; | 491 scoped_ptr<RawSharedBufferMapping> mapping; |
495 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 492 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
496 if (result != MOJO_RESULT_OK) | 493 if (result != MOJO_RESULT_OK) |
497 return result; | 494 return result; |
498 | 495 |
499 DCHECK(mapping); | 496 DCHECK(mapping); |
500 void* address = mapping->base(); | 497 void* address = mapping->base(); |
501 { | 498 { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be | 554 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be |
558 // destroyed, but this would still be required if the waiter were in TLS.) | 555 // destroyed, but this would still be required if the waiter were in TLS.) |
559 for (i = 0; i < num_added; i++) | 556 for (i = 0; i < num_added; i++) |
560 dispatchers[i]->RemoveWaiter(&waiter); | 557 dispatchers[i]->RemoveWaiter(&waiter); |
561 | 558 |
562 return rv; | 559 return rv; |
563 } | 560 } |
564 | 561 |
565 } // namespace system | 562 } // namespace system |
566 } // namespace mojo | 563 } // namespace mojo |
OLD | NEW |