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

Side by Side Diff: mojo/system/core.cc

Issue 419613003: Mojo: Modify plumbing for the WaitMany implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « mojo/system/core.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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"
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 // The dispatcher doesn't have a say in being closed, but gets notified of it. 113 // The dispatcher doesn't have a say in being closed, but gets notified of it.
114 // Note: This is done outside of |handle_table_lock_|. As a result, there's a 114 // Note: This is done outside of |handle_table_lock_|. As a result, there's a
115 // race condition that the dispatcher must handle; see the comment in 115 // race condition that the dispatcher must handle; see the comment in
116 // |Dispatcher| in dispatcher.h. 116 // |Dispatcher| in dispatcher.h.
117 return dispatcher->Close(); 117 return dispatcher->Close();
118 } 118 }
119 119
120 MojoResult Core::Wait(MojoHandle handle, 120 MojoResult Core::Wait(MojoHandle handle,
121 MojoHandleSignals signals, 121 MojoHandleSignals signals,
122 MojoDeadline deadline) { 122 MojoDeadline deadline) {
123 return WaitManyInternal(&handle, &signals, 1, deadline); 123 uint32_t unused = static_cast<uint32_t>(-1);
124 return WaitManyInternal(&handle, &signals, 1, deadline, &unused);
124 } 125 }
125 126
126 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, 127 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles,
127 UserPointer<const MojoHandleSignals> signals, 128 UserPointer<const MojoHandleSignals> signals,
128 uint32_t num_handles, 129 uint32_t num_handles,
129 MojoDeadline deadline) { 130 MojoDeadline deadline) {
130 if (num_handles < 1) 131 if (num_handles < 1)
131 return MOJO_RESULT_INVALID_ARGUMENT; 132 return MOJO_RESULT_INVALID_ARGUMENT;
132 if (num_handles > kMaxWaitManyNumHandles) 133 if (num_handles > kMaxWaitManyNumHandles)
133 return MOJO_RESULT_RESOURCE_EXHAUSTED; 134 return MOJO_RESULT_RESOURCE_EXHAUSTED;
135
134 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); 136 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
135 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, 137 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals,
136 num_handles); 138 num_handles);
137 return WaitManyInternal(handles_reader.GetPointer(), 139 uint32_t result_index = static_cast<uint32_t>(-1);
138 signals_reader.GetPointer(), num_handles, deadline); 140 MojoResult result = WaitManyInternal(handles_reader.GetPointer(),
141 signals_reader.GetPointer(), num_handles,
142 deadline, &result_index);
143 return (result == MOJO_RESULT_OK) ? static_cast<MojoResult>(result_index) :
144 result;
139 } 145 }
140 146
141 MojoResult Core::CreateMessagePipe( 147 MojoResult Core::CreateMessagePipe(
142 UserPointer<const MojoCreateMessagePipeOptions> options, 148 UserPointer<const MojoCreateMessagePipeOptions> options,
143 UserPointer<MojoHandle> message_pipe_handle0, 149 UserPointer<MojoHandle> message_pipe_handle0,
144 UserPointer<MojoHandle> message_pipe_handle1) { 150 UserPointer<MojoHandle> message_pipe_handle1) {
145 MojoCreateMessagePipeOptions validated_options = {}; 151 MojoCreateMessagePipeOptions validated_options = {};
146 // This will verify the |options| pointer. 152 // This will verify the |options| pointer.
147 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions( 153 MojoResult result = MessagePipeDispatcher::ValidateCreateOptions(
148 options.GetPointerUnsafe(), &validated_options); 154 options.GetPointerUnsafe(), &validated_options);
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 return mapping_table_.RemoveMapping(buffer.GetValue()); 516 return mapping_table_.RemoveMapping(buffer.GetValue());
511 } 517 }
512 518
513 // Note: We allow |handles| to repeat the same handle multiple times, since 519 // Note: We allow |handles| to repeat the same handle multiple times, since
514 // different flags may be specified. 520 // different flags may be specified.
515 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this 521 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this
516 // more carefully and address it if necessary. 522 // more carefully and address it if necessary.
517 MojoResult Core::WaitManyInternal(const MojoHandle* handles, 523 MojoResult Core::WaitManyInternal(const MojoHandle* handles,
518 const MojoHandleSignals* signals, 524 const MojoHandleSignals* signals,
519 uint32_t num_handles, 525 uint32_t num_handles,
520 MojoDeadline deadline) { 526 MojoDeadline deadline,
527 uint32_t* result_index) {
521 DCHECK_GT(num_handles, 0u); 528 DCHECK_GT(num_handles, 0u);
529 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1));
522 530
523 DispatcherVector dispatchers; 531 DispatcherVector dispatchers;
524 dispatchers.reserve(num_handles); 532 dispatchers.reserve(num_handles);
525 for (uint32_t i = 0; i < num_handles; i++) { 533 for (uint32_t i = 0; i < num_handles; i++) {
526 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); 534 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]);
527 if (!dispatcher) 535 if (!dispatcher) {
536 *result_index = i;
528 return MOJO_RESULT_INVALID_ARGUMENT; 537 return MOJO_RESULT_INVALID_ARGUMENT;
538 }
529 dispatchers.push_back(dispatcher); 539 dispatchers.push_back(dispatcher);
530 } 540 }
531 541
532 // TODO(vtl): Should make the waiter live (permanently) in TLS. 542 // TODO(vtl): Should make the waiter live (permanently) in TLS.
533 Waiter waiter; 543 Waiter waiter;
534 waiter.Init(); 544 waiter.Init();
535 545
536 uint32_t i; 546 uint32_t i;
537 MojoResult rv = MOJO_RESULT_OK; 547 MojoResult rv = MOJO_RESULT_OK;
538 for (i = 0; i < num_handles; i++) { 548 for (i = 0; i < num_handles; i++) {
539 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i); 549 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i);
540 if (rv != MOJO_RESULT_OK) 550 if (rv != MOJO_RESULT_OK) {
551 *result_index = i;
541 break; 552 break;
553 }
542 } 554 }
543 uint32_t num_added = i; 555 uint32_t num_added = i;
544 556
545 if (rv == MOJO_RESULT_ALREADY_EXISTS) { 557 if (rv == MOJO_RESULT_ALREADY_EXISTS)
546 rv = static_cast<MojoResult>(i); // The i-th one is already "triggered". 558 rv = MOJO_RESULT_OK; // The i-th one is already "triggered".
547 } else if (rv == MOJO_RESULT_OK) { 559 else if (rv == MOJO_RESULT_OK)
548 uint32_t context = static_cast<uint32_t>(-1); 560 rv = waiter.Wait(deadline, result_index);
549 rv = waiter.Wait(deadline, &context);
550 if (rv == MOJO_RESULT_OK)
551 rv = static_cast<MojoResult>(context);
552 }
553 561
554 // Make sure no other dispatchers try to wake |waiter| for the current 562 // Make sure no other dispatchers try to wake |waiter| for the current
555 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be 563 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be
556 // destroyed, but this would still be required if the waiter were in TLS.) 564 // destroyed, but this would still be required if the waiter were in TLS.)
557 for (i = 0; i < num_added; i++) 565 for (i = 0; i < num_added; i++)
558 dispatchers[i]->RemoveWaiter(&waiter); 566 dispatchers[i]->RemoveWaiter(&waiter);
559 567
560 return rv; 568 return rv;
561 } 569 }
562 570
563 } // namespace system 571 } // namespace system
564 } // namespace mojo 572 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698