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

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

Issue 454603002: Mojo: Plumb new Wait/WaitMany API out to Core. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 4 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') | mojo/system/core_unittest.cc » ('j') | 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"
11 #include "mojo/public/c/system/macros.h" 11 #include "mojo/public/c/system/macros.h"
12 #include "mojo/system/constants.h" 12 #include "mojo/system/constants.h"
13 #include "mojo/system/data_pipe.h" 13 #include "mojo/system/data_pipe.h"
14 #include "mojo/system/data_pipe_consumer_dispatcher.h" 14 #include "mojo/system/data_pipe_consumer_dispatcher.h"
15 #include "mojo/system/data_pipe_producer_dispatcher.h" 15 #include "mojo/system/data_pipe_producer_dispatcher.h"
16 #include "mojo/system/dispatcher.h" 16 #include "mojo/system/dispatcher.h"
17 #include "mojo/system/handle_signals_state.h"
17 #include "mojo/system/local_data_pipe.h" 18 #include "mojo/system/local_data_pipe.h"
18 #include "mojo/system/memory.h" 19 #include "mojo/system/memory.h"
19 #include "mojo/system/message_pipe.h" 20 #include "mojo/system/message_pipe.h"
20 #include "mojo/system/message_pipe_dispatcher.h" 21 #include "mojo/system/message_pipe_dispatcher.h"
21 #include "mojo/system/raw_shared_buffer.h" 22 #include "mojo/system/raw_shared_buffer.h"
22 #include "mojo/system/shared_buffer_dispatcher.h" 23 #include "mojo/system/shared_buffer_dispatcher.h"
23 #include "mojo/system/waiter.h" 24 #include "mojo/system/waiter.h"
24 25
25 namespace mojo { 26 namespace mojo {
26 namespace system { 27 namespace system {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 112
112 // 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.
113 // 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
114 // race condition that the dispatcher must handle; see the comment in 115 // race condition that the dispatcher must handle; see the comment in
115 // |Dispatcher| in dispatcher.h. 116 // |Dispatcher| in dispatcher.h.
116 return dispatcher->Close(); 117 return dispatcher->Close();
117 } 118 }
118 119
119 MojoResult Core::Wait(MojoHandle handle, 120 MojoResult Core::Wait(MojoHandle handle,
120 MojoHandleSignals signals, 121 MojoHandleSignals signals,
121 MojoDeadline deadline) { 122 MojoDeadline deadline,
123 UserPointer<MojoHandleSignalsState> signals_state) {
122 uint32_t unused = static_cast<uint32_t>(-1); 124 uint32_t unused = static_cast<uint32_t>(-1);
123 return WaitManyInternal(&handle, &signals, 1, deadline, &unused); 125 HandleSignalsState hss;
126 MojoResult rv = WaitManyInternal(&handle,
127 &signals,
128 1,
129 deadline,
130 &unused,
131 signals_state.IsNull() ? NULL : &hss);
132 if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull())
133 signals_state.Put(hss);
134 return rv;
124 } 135 }
125 136
126 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles, 137 MojoResult Core::WaitMany(UserPointer<const MojoHandle> handles,
127 UserPointer<const MojoHandleSignals> signals, 138 UserPointer<const MojoHandleSignals> signals,
128 uint32_t num_handles, 139 uint32_t num_handles,
129 MojoDeadline deadline) { 140 MojoDeadline deadline,
141 UserPointer<uint32_t> result_index,
142 UserPointer<MojoHandleSignalsState> signals_states) {
130 if (num_handles < 1) 143 if (num_handles < 1)
131 return MOJO_RESULT_INVALID_ARGUMENT; 144 return MOJO_RESULT_INVALID_ARGUMENT;
132 if (num_handles > kMaxWaitManyNumHandles) 145 if (num_handles > kMaxWaitManyNumHandles)
133 return MOJO_RESULT_RESOURCE_EXHAUSTED; 146 return MOJO_RESULT_RESOURCE_EXHAUSTED;
134 147
135 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles); 148 UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
136 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals, 149 UserPointer<const MojoHandleSignals>::Reader signals_reader(signals,
137 num_handles); 150 num_handles);
138 uint32_t result_index = static_cast<uint32_t>(-1); 151 uint32_t index = static_cast<uint32_t>(-1);
139 MojoResult result = WaitManyInternal(handles_reader.GetPointer(), 152 MojoResult rv;
140 signals_reader.GetPointer(), 153 if (signals_states.IsNull()) {
141 num_handles, 154 rv = WaitManyInternal(handles_reader.GetPointer(),
142 deadline, 155 signals_reader.GetPointer(),
143 &result_index); 156 num_handles,
144 return (result == MOJO_RESULT_OK) ? static_cast<MojoResult>(result_index) 157 deadline,
145 : result; 158 &index,
159 NULL);
160 } else {
161 UserPointer<MojoHandleSignalsState>::Writer signals_states_writer(
162 signals_states, num_handles);
163 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a
164 // subclass of |MojoHandleSignalsState| that doesn't add any data members.
165 rv = WaitManyInternal(handles_reader.GetPointer(),
166 signals_reader.GetPointer(),
167 num_handles,
168 deadline,
169 &index,
170 reinterpret_cast<HandleSignalsState*>(
171 signals_states_writer.GetPointer()));
172 if (rv != MOJO_RESULT_INVALID_ARGUMENT)
173 signals_states_writer.Commit();
174 }
175 if (index != static_cast<uint32_t>(-1) && !result_index.IsNull())
176 result_index.Put(index);
177 return rv;
146 } 178 }
147 179
148 MojoResult Core::CreateMessagePipe( 180 MojoResult Core::CreateMessagePipe(
149 UserPointer<const MojoCreateMessagePipeOptions> options, 181 UserPointer<const MojoCreateMessagePipeOptions> options,
150 UserPointer<MojoHandle> message_pipe_handle0, 182 UserPointer<MojoHandle> message_pipe_handle0,
151 UserPointer<MojoHandle> message_pipe_handle1) { 183 UserPointer<MojoHandle> message_pipe_handle1) {
152 MojoCreateMessagePipeOptions validated_options = {}; 184 MojoCreateMessagePipeOptions validated_options = {};
153 MojoResult result = 185 MojoResult result =
154 MessagePipeDispatcher::ValidateCreateOptions(options, &validated_options); 186 MessagePipeDispatcher::ValidateCreateOptions(options, &validated_options);
155 if (result != MOJO_RESULT_OK) 187 if (result != MOJO_RESULT_OK)
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 540 }
509 541
510 // Note: We allow |handles| to repeat the same handle multiple times, since 542 // Note: We allow |handles| to repeat the same handle multiple times, since
511 // different flags may be specified. 543 // different flags may be specified.
512 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this 544 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this
513 // more carefully and address it if necessary. 545 // more carefully and address it if necessary.
514 MojoResult Core::WaitManyInternal(const MojoHandle* handles, 546 MojoResult Core::WaitManyInternal(const MojoHandle* handles,
515 const MojoHandleSignals* signals, 547 const MojoHandleSignals* signals,
516 uint32_t num_handles, 548 uint32_t num_handles,
517 MojoDeadline deadline, 549 MojoDeadline deadline,
518 uint32_t* result_index) { 550 uint32_t* result_index,
551 HandleSignalsState* signals_states) {
519 DCHECK_GT(num_handles, 0u); 552 DCHECK_GT(num_handles, 0u);
520 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1)); 553 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1));
521 554
522 DispatcherVector dispatchers; 555 DispatcherVector dispatchers;
523 dispatchers.reserve(num_handles); 556 dispatchers.reserve(num_handles);
524 for (uint32_t i = 0; i < num_handles; i++) { 557 for (uint32_t i = 0; i < num_handles; i++) {
525 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); 558 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]);
526 if (!dispatcher) { 559 if (!dispatcher) {
527 *result_index = i; 560 *result_index = i;
528 return MOJO_RESULT_INVALID_ARGUMENT; 561 return MOJO_RESULT_INVALID_ARGUMENT;
529 } 562 }
530 dispatchers.push_back(dispatcher); 563 dispatchers.push_back(dispatcher);
531 } 564 }
532 565
533 // TODO(vtl): Should make the waiter live (permanently) in TLS. 566 // TODO(vtl): Should make the waiter live (permanently) in TLS.
534 Waiter waiter; 567 Waiter waiter;
535 waiter.Init(); 568 waiter.Init();
536 569
537 uint32_t i; 570 uint32_t i;
538 MojoResult rv = MOJO_RESULT_OK; 571 MojoResult rv = MOJO_RESULT_OK;
539 for (i = 0; i < num_handles; i++) { 572 for (i = 0; i < num_handles; i++) {
540 rv = dispatchers[i]->AddWaiter(&waiter, signals[i], i, NULL); 573 rv = dispatchers[i]->AddWaiter(
574 &waiter, signals[i], i, signals_states ? &signals_states[i] : NULL);
541 if (rv != MOJO_RESULT_OK) { 575 if (rv != MOJO_RESULT_OK) {
542 *result_index = i; 576 *result_index = i;
543 break; 577 break;
544 } 578 }
545 } 579 }
546 uint32_t num_added = i; 580 uint32_t num_added = i;
547 581
548 if (rv == MOJO_RESULT_ALREADY_EXISTS) 582 if (rv == MOJO_RESULT_ALREADY_EXISTS)
549 rv = MOJO_RESULT_OK; // The i-th one is already "triggered". 583 rv = MOJO_RESULT_OK; // The i-th one is already "triggered".
550 else if (rv == MOJO_RESULT_OK) 584 else if (rv == MOJO_RESULT_OK)
551 rv = waiter.Wait(deadline, result_index); 585 rv = waiter.Wait(deadline, result_index);
552 586
553 // Make sure no other dispatchers try to wake |waiter| for the current 587 // Make sure no other dispatchers try to wake |waiter| for the current
554 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be 588 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be
555 // destroyed, but this would still be required if the waiter were in TLS.) 589 // destroyed, but this would still be required if the waiter were in TLS.)
556 for (i = 0; i < num_added; i++) 590 for (i = 0; i < num_added; i++) {
557 dispatchers[i]->RemoveWaiter(&waiter, NULL); 591 dispatchers[i]->RemoveWaiter(&waiter,
592 signals_states ? &signals_states[i] : NULL);
593 }
594 if (signals_states) {
595 for (; i < num_handles; i++)
596 signals_states[i] = dispatchers[i]->GetHandleSignalsState();
597 }
558 598
559 return rv; 599 return rv;
560 } 600 }
561 601
562 } // namespace system 602 } // namespace system
563 } // namespace mojo 603 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/core.h ('k') | mojo/system/core_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698