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/edk/system/core.h" | 5 #include "mojo/edk/system/core.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // to take another |Dispatcher| lock. (This has consequences on the | 83 // to take another |Dispatcher| lock. (This has consequences on the |
84 // concurrency semantics of |MojoWriteMessage()| when passing handles.) | 84 // concurrency semantics of |MojoWriteMessage()| when passing handles.) |
85 // Doing so would lead to deadlock. | 85 // Doing so would lead to deadlock. |
86 // - Locks at the "INF" level may not have any locks taken while they are | 86 // - Locks at the "INF" level may not have any locks taken while they are |
87 // held. | 87 // held. |
88 | 88 |
89 Core::Core(embedder::PlatformSupport* platform_support) | 89 Core::Core(embedder::PlatformSupport* platform_support) |
90 : platform_support_(platform_support), | 90 : platform_support_(platform_support), |
91 handle_table_(GetConfiguration().max_handle_table_size) {} | 91 handle_table_(GetConfiguration().max_handle_table_size) {} |
92 | 92 |
93 Core::~Core() { | 93 Core::~Core() {} |
94 } | |
95 | 94 |
96 MojoHandle Core::AddHandle(Handle&& handle) { | 95 MojoHandle Core::AddHandle(Handle&& handle) { |
97 MutexLocker locker(&handle_table_mutex_); | 96 MutexLocker locker(&handle_table_mutex_); |
98 return handle_table_.AddHandle(std::move(handle)); | 97 return handle_table_.AddHandle(std::move(handle)); |
99 } | 98 } |
100 | 99 |
101 MojoResult Core::GetDispatcher(MojoHandle handle, | 100 MojoResult Core::GetHandle(MojoHandle handle, Handle* h) { |
102 RefPtr<Dispatcher>* dispatcher) { | |
103 if (handle == MOJO_HANDLE_INVALID) | 101 if (handle == MOJO_HANDLE_INVALID) |
104 return MOJO_RESULT_INVALID_ARGUMENT; | 102 return MOJO_RESULT_INVALID_ARGUMENT; |
105 | 103 |
106 MutexLocker locker(&handle_table_mutex_); | 104 MutexLocker locker(&handle_table_mutex_); |
| 105 return handle_table_.GetHandle(handle, h); |
| 106 } |
| 107 |
| 108 MojoResult Core::GetDispatcher(MojoHandle handle, |
| 109 RefPtr<Dispatcher>* dispatcher) { |
107 Handle h; | 110 Handle h; |
108 MojoResult rv = handle_table_.GetHandle(handle, &h); | 111 MojoResult result = GetHandle(handle, &h); |
109 if (rv == MOJO_RESULT_OK) | 112 if (result == MOJO_RESULT_OK) |
110 *dispatcher = std::move(h.dispatcher); | 113 *dispatcher = std::move(h.dispatcher); |
111 return rv; | 114 return result; |
112 } | 115 } |
113 | 116 |
114 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, | 117 MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, |
115 RefPtr<Dispatcher>* dispatcher) { | 118 RefPtr<Dispatcher>* dispatcher) { |
116 if (handle == MOJO_HANDLE_INVALID) | 119 if (handle == MOJO_HANDLE_INVALID) |
117 return MOJO_RESULT_INVALID_ARGUMENT; | 120 return MOJO_RESULT_INVALID_ARGUMENT; |
118 | 121 |
119 MutexLocker locker(&handle_table_mutex_); | 122 MutexLocker locker(&handle_table_mutex_); |
120 Handle h; | 123 Handle h; |
121 MojoResult rv = handle_table_.GetAndRemoveHandle(handle, &h); | 124 MojoResult result = handle_table_.GetAndRemoveHandle(handle, &h); |
122 if (rv == MOJO_RESULT_OK) | 125 if (result == MOJO_RESULT_OK) |
123 *dispatcher = std::move(h.dispatcher); | 126 *dispatcher = std::move(h.dispatcher); |
124 return rv; | 127 return result; |
| 128 } |
| 129 |
| 130 MojoResult Core::GetDispatcherAndCheckRights( |
| 131 MojoHandle handle, |
| 132 MojoHandleRights required_handle_rights, |
| 133 EntrypointClass entrypoint_class, |
| 134 util::RefPtr<Dispatcher>* dispatcher) { |
| 135 if (handle == MOJO_HANDLE_INVALID) |
| 136 return MOJO_RESULT_INVALID_ARGUMENT; |
| 137 |
| 138 Handle h; |
| 139 MojoResult result = GetHandle(handle, &h); |
| 140 if (result != MOJO_RESULT_OK) |
| 141 return result; |
| 142 |
| 143 if ((h.rights & required_handle_rights) != required_handle_rights) { |
| 144 return h.dispatcher->SupportsEntrypointClass(entrypoint_class) |
| 145 ? MOJO_RESULT_PERMISSION_DENIED |
| 146 : MOJO_RESULT_INVALID_ARGUMENT; |
| 147 } |
| 148 |
| 149 *dispatcher = std::move(h.dispatcher); |
| 150 return MOJO_RESULT_OK; |
125 } | 151 } |
126 | 152 |
127 MojoResult Core::AsyncWait(MojoHandle handle, | 153 MojoResult Core::AsyncWait(MojoHandle handle, |
128 MojoHandleSignals signals, | 154 MojoHandleSignals signals, |
129 const std::function<void(MojoResult)>& callback) { | 155 const std::function<void(MojoResult)>& callback) { |
130 RefPtr<Dispatcher> dispatcher; | 156 RefPtr<Dispatcher> dispatcher; |
131 MojoResult result = GetDispatcher(handle, &dispatcher); | 157 MojoResult result = GetDispatcherAndCheckRights( |
| 158 handle, MOJO_HANDLE_RIGHT_NONE, EntrypointClass::NONE, &dispatcher); |
132 if (result != MOJO_RESULT_OK) | 159 if (result != MOJO_RESULT_OK) |
133 return result; | 160 return result; |
134 | 161 |
135 std::unique_ptr<AsyncWaiter> waiter(new AsyncWaiter(callback)); | 162 std::unique_ptr<AsyncWaiter> waiter(new AsyncWaiter(callback)); |
136 result = dispatcher->AddAwakable(waiter.get(), signals, 0, nullptr); | 163 result = dispatcher->AddAwakable(waiter.get(), signals, 0, nullptr); |
137 if (result == MOJO_RESULT_OK) | 164 if (result == MOJO_RESULT_OK) |
138 ignore_result(waiter.release()); | 165 ignore_result(waiter.release()); |
139 return result; | 166 return result; |
140 } | 167 } |
141 | 168 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 // isn't done, in the in-process case, calls on the old handle may complete | 285 // isn't done, in the in-process case, calls on the old handle may complete |
259 // after the the message has been received and a new handle created (and | 286 // after the the message has been received and a new handle created (and |
260 // possibly even after calls have been made on the new handle). | 287 // possibly even after calls have been made on the new handle). |
261 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 288 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
262 UserPointer<const void> bytes, | 289 UserPointer<const void> bytes, |
263 uint32_t num_bytes, | 290 uint32_t num_bytes, |
264 UserPointer<const MojoHandle> handles, | 291 UserPointer<const MojoHandle> handles, |
265 uint32_t num_handles, | 292 uint32_t num_handles, |
266 MojoWriteMessageFlags flags) { | 293 MojoWriteMessageFlags flags) { |
267 RefPtr<Dispatcher> dispatcher; | 294 RefPtr<Dispatcher> dispatcher; |
268 MojoResult result = GetDispatcher(message_pipe_handle, &dispatcher); | 295 MojoResult result = |
| 296 GetDispatcherAndCheckRights(message_pipe_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 297 EntrypointClass::MESSAGE_PIPE, &dispatcher); |
269 if (result != MOJO_RESULT_OK) | 298 if (result != MOJO_RESULT_OK) |
270 return result; | 299 return result; |
271 | 300 |
272 // Easy case: not sending any handles. | 301 // Easy case: not sending any handles. |
273 if (num_handles == 0) | 302 if (num_handles == 0) |
274 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); | 303 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); |
275 | 304 |
276 // We have to handle |handles| here, since we have to mark them busy in the | 305 // We have to handle |handles| here, since we have to mark them busy in the |
277 // global handle table. We can't delegate this to the dispatcher, since the | 306 // global handle table. We can't delegate this to the dispatcher, since the |
278 // handle table lock must be acquired before the dispatcher lock. | 307 // handle table lock must be acquired before the dispatcher lock. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 return result; | 354 return result; |
326 } | 355 } |
327 | 356 |
328 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, | 357 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, |
329 UserPointer<void> bytes, | 358 UserPointer<void> bytes, |
330 UserPointer<uint32_t> num_bytes, | 359 UserPointer<uint32_t> num_bytes, |
331 UserPointer<MojoHandle> handles, | 360 UserPointer<MojoHandle> handles, |
332 UserPointer<uint32_t> num_handles, | 361 UserPointer<uint32_t> num_handles, |
333 MojoReadMessageFlags flags) { | 362 MojoReadMessageFlags flags) { |
334 RefPtr<Dispatcher> dispatcher; | 363 RefPtr<Dispatcher> dispatcher; |
335 MojoResult result = GetDispatcher(message_pipe_handle, &dispatcher); | 364 MojoResult result = |
| 365 GetDispatcherAndCheckRights(message_pipe_handle, MOJO_HANDLE_RIGHT_READ, |
| 366 EntrypointClass::MESSAGE_PIPE, &dispatcher); |
336 if (result != MOJO_RESULT_OK) | 367 if (result != MOJO_RESULT_OK) |
337 return result; | 368 return result; |
338 | 369 |
339 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); | 370 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); |
340 | 371 |
341 if (num_handles_value == 0) { | 372 if (num_handles_value == 0) { |
342 // Easy case: won't receive any handles. | 373 // Easy case: won't receive any handles. |
343 result = dispatcher->ReadMessage(bytes, num_bytes, nullptr, | 374 result = dispatcher->ReadMessage(bytes, num_bytes, nullptr, |
344 &num_handles_value, flags); | 375 &num_handles_value, flags); |
345 } else { | 376 } else { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 | 447 |
417 data_pipe_producer_handle.Put(handle_pair.first); | 448 data_pipe_producer_handle.Put(handle_pair.first); |
418 data_pipe_consumer_handle.Put(handle_pair.second); | 449 data_pipe_consumer_handle.Put(handle_pair.second); |
419 return MOJO_RESULT_OK; | 450 return MOJO_RESULT_OK; |
420 } | 451 } |
421 | 452 |
422 MojoResult Core::SetDataPipeProducerOptions( | 453 MojoResult Core::SetDataPipeProducerOptions( |
423 MojoHandle data_pipe_producer_handle, | 454 MojoHandle data_pipe_producer_handle, |
424 UserPointer<const MojoDataPipeProducerOptions> options) { | 455 UserPointer<const MojoDataPipeProducerOptions> options) { |
425 RefPtr<Dispatcher> dispatcher; | 456 RefPtr<Dispatcher> dispatcher; |
426 MojoResult result = GetDispatcher(data_pipe_producer_handle, &dispatcher); | 457 MojoResult result = GetDispatcherAndCheckRights( |
| 458 data_pipe_producer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 459 EntrypointClass::DATA_PIPE_PRODUCER, &dispatcher); |
427 if (result != MOJO_RESULT_OK) | 460 if (result != MOJO_RESULT_OK) |
428 return result; | 461 return result; |
429 | 462 |
430 return dispatcher->SetDataPipeProducerOptions(options); | 463 return dispatcher->SetDataPipeProducerOptions(options); |
431 } | 464 } |
432 | 465 |
433 MojoResult Core::GetDataPipeProducerOptions( | 466 MojoResult Core::GetDataPipeProducerOptions( |
434 MojoHandle data_pipe_producer_handle, | 467 MojoHandle data_pipe_producer_handle, |
435 UserPointer<MojoDataPipeProducerOptions> options, | 468 UserPointer<MojoDataPipeProducerOptions> options, |
436 uint32_t options_num_bytes) { | 469 uint32_t options_num_bytes) { |
437 RefPtr<Dispatcher> dispatcher; | 470 RefPtr<Dispatcher> dispatcher; |
438 MojoResult result = GetDispatcher(data_pipe_producer_handle, &dispatcher); | 471 MojoResult result = GetDispatcherAndCheckRights( |
| 472 data_pipe_producer_handle, MOJO_HANDLE_RIGHT_READ, |
| 473 EntrypointClass::DATA_PIPE_PRODUCER, &dispatcher); |
439 if (result != MOJO_RESULT_OK) | 474 if (result != MOJO_RESULT_OK) |
440 return result; | 475 return result; |
441 | 476 |
442 return dispatcher->GetDataPipeProducerOptions(options, options_num_bytes); | 477 return dispatcher->GetDataPipeProducerOptions(options, options_num_bytes); |
443 } | 478 } |
444 | 479 |
445 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, | 480 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, |
446 UserPointer<const void> elements, | 481 UserPointer<const void> elements, |
447 UserPointer<uint32_t> num_bytes, | 482 UserPointer<uint32_t> num_bytes, |
448 MojoWriteDataFlags flags) { | 483 MojoWriteDataFlags flags) { |
449 RefPtr<Dispatcher> dispatcher; | 484 RefPtr<Dispatcher> dispatcher; |
450 MojoResult result = GetDispatcher(data_pipe_producer_handle, &dispatcher); | 485 MojoResult result = GetDispatcherAndCheckRights( |
| 486 data_pipe_producer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 487 EntrypointClass::DATA_PIPE_PRODUCER, &dispatcher); |
451 if (result != MOJO_RESULT_OK) | 488 if (result != MOJO_RESULT_OK) |
452 return result; | 489 return result; |
453 | 490 |
454 return dispatcher->WriteData(elements, num_bytes, flags); | 491 return dispatcher->WriteData(elements, num_bytes, flags); |
455 } | 492 } |
456 | 493 |
457 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, | 494 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, |
458 UserPointer<void*> buffer, | 495 UserPointer<void*> buffer, |
459 UserPointer<uint32_t> buffer_num_bytes, | 496 UserPointer<uint32_t> buffer_num_bytes, |
460 MojoWriteDataFlags flags) { | 497 MojoWriteDataFlags flags) { |
461 RefPtr<Dispatcher> dispatcher; | 498 RefPtr<Dispatcher> dispatcher; |
462 MojoResult result = GetDispatcher(data_pipe_producer_handle, &dispatcher); | 499 MojoResult result = GetDispatcherAndCheckRights( |
| 500 data_pipe_producer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 501 EntrypointClass::DATA_PIPE_PRODUCER, &dispatcher); |
463 if (result != MOJO_RESULT_OK) | 502 if (result != MOJO_RESULT_OK) |
464 return result; | 503 return result; |
465 | 504 |
466 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); | 505 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); |
467 } | 506 } |
468 | 507 |
469 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, | 508 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, |
470 uint32_t num_bytes_written) { | 509 uint32_t num_bytes_written) { |
471 RefPtr<Dispatcher> dispatcher; | 510 RefPtr<Dispatcher> dispatcher; |
472 MojoResult result = GetDispatcher(data_pipe_producer_handle, &dispatcher); | 511 MojoResult result = GetDispatcherAndCheckRights( |
| 512 data_pipe_producer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 513 EntrypointClass::DATA_PIPE_PRODUCER, &dispatcher); |
473 if (result != MOJO_RESULT_OK) | 514 if (result != MOJO_RESULT_OK) |
474 return result; | 515 return result; |
475 | 516 |
476 return dispatcher->EndWriteData(num_bytes_written); | 517 return dispatcher->EndWriteData(num_bytes_written); |
477 } | 518 } |
478 | 519 |
479 MojoResult Core::SetDataPipeConsumerOptions( | 520 MojoResult Core::SetDataPipeConsumerOptions( |
480 MojoHandle data_pipe_consumer_handle, | 521 MojoHandle data_pipe_consumer_handle, |
481 UserPointer<const MojoDataPipeConsumerOptions> options) { | 522 UserPointer<const MojoDataPipeConsumerOptions> options) { |
482 RefPtr<Dispatcher> dispatcher; | 523 RefPtr<Dispatcher> dispatcher; |
483 MojoResult result = GetDispatcher(data_pipe_consumer_handle, &dispatcher); | 524 MojoResult result = GetDispatcherAndCheckRights( |
| 525 data_pipe_consumer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 526 EntrypointClass::DATA_PIPE_CONSUMER, &dispatcher); |
484 if (result != MOJO_RESULT_OK) | 527 if (result != MOJO_RESULT_OK) |
485 return result; | 528 return result; |
486 | 529 |
487 return dispatcher->SetDataPipeConsumerOptions(options); | 530 return dispatcher->SetDataPipeConsumerOptions(options); |
488 } | 531 } |
489 | 532 |
490 MojoResult Core::GetDataPipeConsumerOptions( | 533 MojoResult Core::GetDataPipeConsumerOptions( |
491 MojoHandle data_pipe_consumer_handle, | 534 MojoHandle data_pipe_consumer_handle, |
492 UserPointer<MojoDataPipeConsumerOptions> options, | 535 UserPointer<MojoDataPipeConsumerOptions> options, |
493 uint32_t options_num_bytes) { | 536 uint32_t options_num_bytes) { |
494 RefPtr<Dispatcher> dispatcher; | 537 RefPtr<Dispatcher> dispatcher; |
495 MojoResult result = GetDispatcher(data_pipe_consumer_handle, &dispatcher); | 538 MojoResult result = GetDispatcherAndCheckRights( |
| 539 data_pipe_consumer_handle, MOJO_HANDLE_RIGHT_READ, |
| 540 EntrypointClass::DATA_PIPE_CONSUMER, &dispatcher); |
496 if (result != MOJO_RESULT_OK) | 541 if (result != MOJO_RESULT_OK) |
497 return result; | 542 return result; |
498 | 543 |
499 return dispatcher->GetDataPipeConsumerOptions(options, options_num_bytes); | 544 return dispatcher->GetDataPipeConsumerOptions(options, options_num_bytes); |
500 } | 545 } |
501 | 546 |
502 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, | 547 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, |
503 UserPointer<void> elements, | 548 UserPointer<void> elements, |
504 UserPointer<uint32_t> num_bytes, | 549 UserPointer<uint32_t> num_bytes, |
505 MojoReadDataFlags flags) { | 550 MojoReadDataFlags flags) { |
506 RefPtr<Dispatcher> dispatcher; | 551 RefPtr<Dispatcher> dispatcher; |
507 MojoResult result = GetDispatcher(data_pipe_consumer_handle, &dispatcher); | 552 MojoResult result = GetDispatcherAndCheckRights( |
| 553 data_pipe_consumer_handle, MOJO_HANDLE_RIGHT_READ, |
| 554 EntrypointClass::DATA_PIPE_CONSUMER, &dispatcher); |
508 if (result != MOJO_RESULT_OK) | 555 if (result != MOJO_RESULT_OK) |
509 return result; | 556 return result; |
510 | 557 |
511 return dispatcher->ReadData(elements, num_bytes, flags); | 558 return dispatcher->ReadData(elements, num_bytes, flags); |
512 } | 559 } |
513 | 560 |
514 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, | 561 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, |
515 UserPointer<const void*> buffer, | 562 UserPointer<const void*> buffer, |
516 UserPointer<uint32_t> buffer_num_bytes, | 563 UserPointer<uint32_t> buffer_num_bytes, |
517 MojoReadDataFlags flags) { | 564 MojoReadDataFlags flags) { |
518 RefPtr<Dispatcher> dispatcher; | 565 RefPtr<Dispatcher> dispatcher; |
519 MojoResult result = GetDispatcher(data_pipe_consumer_handle, &dispatcher); | 566 MojoResult result = GetDispatcherAndCheckRights( |
| 567 data_pipe_consumer_handle, MOJO_HANDLE_RIGHT_READ, |
| 568 EntrypointClass::DATA_PIPE_CONSUMER, &dispatcher); |
520 if (result != MOJO_RESULT_OK) | 569 if (result != MOJO_RESULT_OK) |
521 return result; | 570 return result; |
522 | 571 |
523 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); | 572 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); |
524 } | 573 } |
525 | 574 |
526 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, | 575 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, |
527 uint32_t num_bytes_read) { | 576 uint32_t num_bytes_read) { |
528 RefPtr<Dispatcher> dispatcher; | 577 RefPtr<Dispatcher> dispatcher; |
529 MojoResult result = GetDispatcher(data_pipe_consumer_handle, &dispatcher); | 578 MojoResult result = GetDispatcherAndCheckRights( |
| 579 data_pipe_consumer_handle, MOJO_HANDLE_RIGHT_READ, |
| 580 EntrypointClass::DATA_PIPE_CONSUMER, &dispatcher); |
530 if (result != MOJO_RESULT_OK) | 581 if (result != MOJO_RESULT_OK) |
531 return result; | 582 return result; |
532 | 583 |
533 return dispatcher->EndReadData(num_bytes_read); | 584 return dispatcher->EndReadData(num_bytes_read); |
534 } | 585 } |
535 | 586 |
536 MojoResult Core::CreateSharedBuffer( | 587 MojoResult Core::CreateSharedBuffer( |
537 UserPointer<const MojoCreateSharedBufferOptions> options, | 588 UserPointer<const MojoCreateSharedBufferOptions> options, |
538 uint64_t num_bytes, | 589 uint64_t num_bytes, |
539 UserPointer<MojoHandle> shared_buffer_handle) { | 590 UserPointer<MojoHandle> shared_buffer_handle) { |
(...skipping 19 matching lines...) Expand all Loading... |
559 } | 610 } |
560 | 611 |
561 shared_buffer_handle.Put(h); | 612 shared_buffer_handle.Put(h); |
562 return MOJO_RESULT_OK; | 613 return MOJO_RESULT_OK; |
563 } | 614 } |
564 | 615 |
565 MojoResult Core::DuplicateBufferHandle( | 616 MojoResult Core::DuplicateBufferHandle( |
566 MojoHandle buffer_handle, | 617 MojoHandle buffer_handle, |
567 UserPointer<const MojoDuplicateBufferHandleOptions> options, | 618 UserPointer<const MojoDuplicateBufferHandleOptions> options, |
568 UserPointer<MojoHandle> new_buffer_handle) { | 619 UserPointer<MojoHandle> new_buffer_handle) { |
569 RefPtr<Dispatcher> dispatcher; | 620 // TODO(vtl): This is a big ugly and duplicates some code, but the plan is to |
570 MojoResult result = GetDispatcher(buffer_handle, &dispatcher); | 621 // remove this method anyway. |
| 622 Handle h; |
| 623 MojoResult result = GetHandle(buffer_handle, &h); |
571 if (result != MOJO_RESULT_OK) | 624 if (result != MOJO_RESULT_OK) |
572 return result; | 625 return result; |
573 | 626 |
| 627 if (!(h.rights & MOJO_HANDLE_RIGHT_DUPLICATE)) { |
| 628 return h.dispatcher->SupportsEntrypointClass(EntrypointClass::BUFFER) |
| 629 ? MOJO_RESULT_PERMISSION_DENIED |
| 630 : MOJO_RESULT_INVALID_ARGUMENT; |
| 631 } |
| 632 |
574 // Don't verify |options| here; that's the dispatcher's job. | 633 // Don't verify |options| here; that's the dispatcher's job. |
575 RefPtr<Dispatcher> new_dispatcher; | 634 RefPtr<Dispatcher> new_dispatcher; |
576 result = dispatcher->DuplicateBufferHandle(options, &new_dispatcher); | 635 result = h.dispatcher->DuplicateBufferHandle(options, &new_dispatcher); |
577 if (result != MOJO_RESULT_OK) | 636 if (result != MOJO_RESULT_OK) |
578 return result; | 637 return result; |
579 | 638 |
580 // TODO(vtl): This should be done with the original handle's rights. | 639 MojoHandle new_handle = AddHandle(Handle(new_dispatcher.Clone(), h.rights)); |
581 MojoHandle new_handle = AddHandle(Handle( | |
582 new_dispatcher.Clone(), SharedBufferDispatcher::kDefaultHandleRights)); | |
583 if (new_handle == MOJO_HANDLE_INVALID) { | 640 if (new_handle == MOJO_HANDLE_INVALID) { |
584 LOG(ERROR) << "Handle table full"; | 641 LOG(ERROR) << "Handle table full"; |
585 new_dispatcher->Close(); | 642 new_dispatcher->Close(); |
586 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 643 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
587 } | 644 } |
588 | 645 |
589 new_buffer_handle.Put(new_handle); | 646 new_buffer_handle.Put(new_handle); |
590 return MOJO_RESULT_OK; | 647 return MOJO_RESULT_OK; |
591 } | 648 } |
592 | 649 |
593 MojoResult Core::GetBufferInformation(MojoHandle buffer_handle, | 650 MojoResult Core::GetBufferInformation(MojoHandle buffer_handle, |
594 UserPointer<MojoBufferInformation> info, | 651 UserPointer<MojoBufferInformation> info, |
595 uint32_t info_num_bytes) { | 652 uint32_t info_num_bytes) { |
596 RefPtr<Dispatcher> dispatcher; | 653 RefPtr<Dispatcher> dispatcher; |
597 MojoResult result = GetDispatcher(buffer_handle, &dispatcher); | 654 MojoResult result = |
| 655 GetDispatcherAndCheckRights(buffer_handle, MOJO_HANDLE_RIGHT_READ, |
| 656 EntrypointClass::BUFFER, &dispatcher); |
598 if (result != MOJO_RESULT_OK) | 657 if (result != MOJO_RESULT_OK) |
599 return result; | 658 return result; |
600 | 659 |
601 return dispatcher->GetBufferInformation(info, info_num_bytes); | 660 return dispatcher->GetBufferInformation(info, info_num_bytes); |
602 } | 661 } |
603 | 662 |
604 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 663 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
605 uint64_t offset, | 664 uint64_t offset, |
606 uint64_t num_bytes, | 665 uint64_t num_bytes, |
607 UserPointer<void*> buffer, | 666 UserPointer<void*> buffer, |
608 MojoMapBufferFlags flags) { | 667 MojoMapBufferFlags flags) { |
609 RefPtr<Dispatcher> dispatcher; | 668 RefPtr<Dispatcher> dispatcher; |
610 MojoResult result = GetDispatcher(buffer_handle, &dispatcher); | 669 // TODO(vtl): Is this right? Or should there be a "map" right? Probably I need |
| 670 // to rethink rights for buffers. |
| 671 MojoResult result = |
| 672 GetDispatcherAndCheckRights(buffer_handle, MOJO_HANDLE_RIGHT_WRITE, |
| 673 EntrypointClass::BUFFER, &dispatcher); |
611 if (result != MOJO_RESULT_OK) | 674 if (result != MOJO_RESULT_OK) |
612 return result; | 675 return result; |
613 | 676 |
614 std::unique_ptr<PlatformSharedBufferMapping> mapping; | 677 std::unique_ptr<PlatformSharedBufferMapping> mapping; |
615 result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 678 result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
616 if (result != MOJO_RESULT_OK) | 679 if (result != MOJO_RESULT_OK) |
617 return result; | 680 return result; |
618 | 681 |
619 DCHECK(mapping); | 682 DCHECK(mapping); |
620 void* address = mapping->GetBase(); | 683 void* address = mapping->GetBase(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 if (signals_states) { | 762 if (signals_states) { |
700 for (; i < num_handles; i++) | 763 for (; i < num_handles; i++) |
701 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); | 764 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); |
702 } | 765 } |
703 | 766 |
704 return result; | 767 return result; |
705 } | 768 } |
706 | 769 |
707 } // namespace system | 770 } // namespace system |
708 } // namespace mojo | 771 } // namespace mojo |
OLD | NEW |