Reset on-screen keyboard on a change to the active user.
[chromium-blink-merge.git] / mojo / system / dispatcher.cc
blob16735fc87c671812987f837198756563e9aedc17
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
3 // found in the LICENSE file.
5 #include "mojo/system/dispatcher.h"
7 #include "base/logging.h"
8 #include "mojo/system/constants.h"
9 #include "mojo/system/message_pipe_dispatcher.h"
11 namespace mojo {
12 namespace system {
14 namespace test {
16 // TODO(vtl): Maybe this should be defined in a test-only file instead.
17 DispatcherTransport DispatcherTryStartTransport(
18 Dispatcher* dispatcher) {
19 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
22 } // namespace test
24 // Dispatcher ------------------------------------------------------------------
26 // static
27 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
28 Dispatcher* dispatcher) {
29 DCHECK(dispatcher);
31 if (!dispatcher->lock_.Try())
32 return DispatcherTransport();
34 // We shouldn't race with things that close dispatchers, since closing can
35 // only take place either under |handle_table_lock_| or when the handle is
36 // marked as busy.
37 DCHECK(!dispatcher->is_closed_);
39 return DispatcherTransport(dispatcher);
42 // static
43 void Dispatcher::TransportDataAccess::StartSerialize(
44 Dispatcher* dispatcher,
45 Channel* channel,
46 size_t* max_size,
47 size_t* max_platform_handles) {
48 DCHECK(dispatcher);
49 dispatcher->StartSerialize(channel, max_size, max_platform_handles);
52 // static
53 bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
54 Dispatcher* dispatcher,
55 Channel* channel,
56 void* destination,
57 size_t* actual_size,
58 std::vector<embedder::PlatformHandle>* platform_handles) {
59 DCHECK(dispatcher);
60 return dispatcher->EndSerializeAndClose(channel, destination, actual_size,
61 platform_handles);
64 // static
65 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
66 Channel* channel,
67 int32_t type,
68 const void* source,
69 size_t size) {
70 switch (static_cast<int32_t>(type)) {
71 case kTypeUnknown:
72 DVLOG(2) << "Deserializing invalid handle";
73 return scoped_refptr<Dispatcher>();
74 case kTypeMessagePipe:
75 return scoped_refptr<Dispatcher>(
76 MessagePipeDispatcher::Deserialize(channel, source, size));
77 case kTypeDataPipeProducer:
78 case kTypeDataPipeConsumer:
79 LOG(WARNING) << "Deserialization of dispatcher type " << type
80 << " not supported";
81 return scoped_refptr<Dispatcher>();
83 LOG(WARNING) << "Unknown dispatcher type " << type;
84 return scoped_refptr<Dispatcher>();
87 MojoResult Dispatcher::Close() {
88 base::AutoLock locker(lock_);
89 if (is_closed_)
90 return MOJO_RESULT_INVALID_ARGUMENT;
92 CloseNoLock();
93 return MOJO_RESULT_OK;
96 MojoResult Dispatcher::WriteMessage(
97 const void* bytes,
98 uint32_t num_bytes,
99 std::vector<DispatcherTransport>* transports,
100 MojoWriteMessageFlags flags) {
101 DCHECK(!transports || (transports->size() > 0 &&
102 transports->size() < kMaxMessageNumHandles));
104 base::AutoLock locker(lock_);
105 if (is_closed_)
106 return MOJO_RESULT_INVALID_ARGUMENT;
108 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
111 MojoResult Dispatcher::ReadMessage(void* bytes,
112 uint32_t* num_bytes,
113 DispatcherVector* dispatchers,
114 uint32_t* num_dispatchers,
115 MojoReadMessageFlags flags) {
116 DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
117 (dispatchers && dispatchers->empty()));
119 base::AutoLock locker(lock_);
120 if (is_closed_)
121 return MOJO_RESULT_INVALID_ARGUMENT;
123 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
124 flags);
127 MojoResult Dispatcher::WriteData(const void* elements,
128 uint32_t* num_bytes,
129 MojoWriteDataFlags flags) {
130 base::AutoLock locker(lock_);
131 if (is_closed_)
132 return MOJO_RESULT_INVALID_ARGUMENT;
134 return WriteDataImplNoLock(elements, num_bytes, flags);
137 MojoResult Dispatcher::BeginWriteData(void** buffer,
138 uint32_t* buffer_num_bytes,
139 MojoWriteDataFlags flags) {
140 base::AutoLock locker(lock_);
141 if (is_closed_)
142 return MOJO_RESULT_INVALID_ARGUMENT;
144 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
147 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
148 base::AutoLock locker(lock_);
149 if (is_closed_)
150 return MOJO_RESULT_INVALID_ARGUMENT;
152 return EndWriteDataImplNoLock(num_bytes_written);
155 MojoResult Dispatcher::ReadData(void* elements,
156 uint32_t* num_bytes,
157 MojoReadDataFlags flags) {
158 base::AutoLock locker(lock_);
159 if (is_closed_)
160 return MOJO_RESULT_INVALID_ARGUMENT;
162 return ReadDataImplNoLock(elements, num_bytes, flags);
165 MojoResult Dispatcher::BeginReadData(const void** buffer,
166 uint32_t* buffer_num_bytes,
167 MojoReadDataFlags flags) {
168 base::AutoLock locker(lock_);
169 if (is_closed_)
170 return MOJO_RESULT_INVALID_ARGUMENT;
172 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
175 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
176 base::AutoLock locker(lock_);
177 if (is_closed_)
178 return MOJO_RESULT_INVALID_ARGUMENT;
180 return EndReadDataImplNoLock(num_bytes_read);
183 MojoResult Dispatcher::DuplicateBufferHandle(
184 const MojoDuplicateBufferHandleOptions* options,
185 scoped_refptr<Dispatcher>* new_dispatcher) {
186 base::AutoLock locker(lock_);
187 if (is_closed_)
188 return MOJO_RESULT_INVALID_ARGUMENT;
190 return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
193 MojoResult Dispatcher::MapBuffer(
194 uint64_t offset,
195 uint64_t num_bytes,
196 MojoMapBufferFlags flags,
197 scoped_ptr<RawSharedBufferMapping>* mapping) {
198 base::AutoLock locker(lock_);
199 if (is_closed_)
200 return MOJO_RESULT_INVALID_ARGUMENT;
202 return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
205 MojoResult Dispatcher::AddWaiter(Waiter* waiter,
206 MojoWaitFlags flags,
207 MojoResult wake_result) {
208 DCHECK_GE(wake_result, 0);
210 base::AutoLock locker(lock_);
211 if (is_closed_)
212 return MOJO_RESULT_INVALID_ARGUMENT;
214 return AddWaiterImplNoLock(waiter, flags, wake_result);
217 void Dispatcher::RemoveWaiter(Waiter* waiter) {
218 base::AutoLock locker(lock_);
219 if (is_closed_)
220 return;
221 RemoveWaiterImplNoLock(waiter);
224 Dispatcher::Dispatcher()
225 : is_closed_(false) {
228 Dispatcher::~Dispatcher() {
229 // Make sure that |Close()| was called.
230 DCHECK(is_closed_);
233 void Dispatcher::CancelAllWaitersNoLock() {
234 lock_.AssertAcquired();
235 DCHECK(is_closed_);
236 // By default, waiting isn't supported. Only dispatchers that can be waited on
237 // will do something nontrivial.
240 void Dispatcher::CloseImplNoLock() {
241 lock_.AssertAcquired();
242 DCHECK(is_closed_);
243 // This may not need to do anything. Dispatchers should override this to do
244 // any actual close-time cleanup necessary.
247 MojoResult Dispatcher::WriteMessageImplNoLock(
248 const void* /*bytes*/,
249 uint32_t /*num_bytes*/,
250 std::vector<DispatcherTransport>* /*transports*/,
251 MojoWriteMessageFlags /*flags*/) {
252 lock_.AssertAcquired();
253 DCHECK(!is_closed_);
254 // By default, not supported. Only needed for message pipe dispatchers.
255 return MOJO_RESULT_INVALID_ARGUMENT;
258 MojoResult Dispatcher::ReadMessageImplNoLock(void* /*bytes*/,
259 uint32_t* /*num_bytes*/,
260 DispatcherVector* /*dispatchers*/,
261 uint32_t* /*num_dispatchers*/,
262 MojoReadMessageFlags /*flags*/) {
263 lock_.AssertAcquired();
264 DCHECK(!is_closed_);
265 // By default, not supported. Only needed for message pipe dispatchers.
266 return MOJO_RESULT_INVALID_ARGUMENT;
269 MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/,
270 uint32_t* /*num_bytes*/,
271 MojoWriteDataFlags /*flags*/) {
272 lock_.AssertAcquired();
273 DCHECK(!is_closed_);
274 // By default, not supported. Only needed for data pipe dispatchers.
275 return MOJO_RESULT_INVALID_ARGUMENT;
278 MojoResult Dispatcher::BeginWriteDataImplNoLock(void** /*buffer*/,
279 uint32_t* /*buffer_num_bytes*/,
280 MojoWriteDataFlags /*flags*/) {
281 lock_.AssertAcquired();
282 DCHECK(!is_closed_);
283 // By default, not supported. Only needed for data pipe dispatchers.
284 return MOJO_RESULT_INVALID_ARGUMENT;
287 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
288 lock_.AssertAcquired();
289 DCHECK(!is_closed_);
290 // By default, not supported. Only needed for data pipe dispatchers.
291 return MOJO_RESULT_INVALID_ARGUMENT;
294 MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/,
295 uint32_t* /*num_bytes*/,
296 MojoReadDataFlags /*flags*/) {
297 lock_.AssertAcquired();
298 DCHECK(!is_closed_);
299 // By default, not supported. Only needed for data pipe dispatchers.
300 return MOJO_RESULT_INVALID_ARGUMENT;
303 MojoResult Dispatcher::BeginReadDataImplNoLock(const void** /*buffer*/,
304 uint32_t* /*buffer_num_bytes*/,
305 MojoReadDataFlags /*flags*/) {
306 lock_.AssertAcquired();
307 DCHECK(!is_closed_);
308 // By default, not supported. Only needed for data pipe dispatchers.
309 return MOJO_RESULT_INVALID_ARGUMENT;
312 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
313 lock_.AssertAcquired();
314 DCHECK(!is_closed_);
315 // By default, not supported. Only needed for data pipe dispatchers.
316 return MOJO_RESULT_INVALID_ARGUMENT;
319 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
320 const MojoDuplicateBufferHandleOptions* /*options*/,
321 scoped_refptr<Dispatcher>* /*new_dispatcher*/) {
322 lock_.AssertAcquired();
323 DCHECK(!is_closed_);
324 // By default, not supported. Only needed for buffer dispatchers.
325 return MOJO_RESULT_INVALID_ARGUMENT;
328 MojoResult Dispatcher::MapBufferImplNoLock(
329 uint64_t /*offset*/,
330 uint64_t /*num_bytes*/,
331 MojoMapBufferFlags /*flags*/,
332 scoped_ptr<RawSharedBufferMapping>* /*mapping*/) {
333 lock_.AssertAcquired();
334 DCHECK(!is_closed_);
335 // By default, not supported. Only needed for buffer dispatchers.
336 return MOJO_RESULT_INVALID_ARGUMENT;
339 MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
340 MojoWaitFlags /*flags*/,
341 MojoResult /*wake_result*/) {
342 lock_.AssertAcquired();
343 DCHECK(!is_closed_);
344 // By default, waiting isn't supported. Only dispatchers that can be waited on
345 // will do something nontrivial.
346 return MOJO_RESULT_FAILED_PRECONDITION;
349 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) {
350 lock_.AssertAcquired();
351 DCHECK(!is_closed_);
352 // By default, waiting isn't supported. Only dispatchers that can be waited on
353 // will do something nontrivial.
356 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/,
357 size_t* max_size,
358 size_t* max_platform_handles) {
359 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
360 DCHECK(!is_closed_);
361 *max_size = 0;
362 *max_platform_handles = 0;
365 bool Dispatcher::EndSerializeAndCloseImplNoLock(
366 Channel* /*channel*/,
367 void* /*destination*/,
368 size_t* /*actual_size*/,
369 std::vector<embedder::PlatformHandle>* /*platform_handles*/) {
370 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
371 DCHECK(is_closed_);
372 // By default, serializing isn't supported, so just close.
373 CloseImplNoLock();
374 return false;
377 bool Dispatcher::IsBusyNoLock() const {
378 lock_.AssertAcquired();
379 DCHECK(!is_closed_);
380 // Most dispatchers support only "atomic" operations, so they are never busy
381 // (in this sense).
382 return false;
385 void Dispatcher::CloseNoLock() {
386 lock_.AssertAcquired();
387 DCHECK(!is_closed_);
389 is_closed_ = true;
390 CancelAllWaitersNoLock();
391 CloseImplNoLock();
394 scoped_refptr<Dispatcher>
395 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
396 lock_.AssertAcquired();
397 DCHECK(!is_closed_);
399 is_closed_ = true;
400 CancelAllWaitersNoLock();
401 return CreateEquivalentDispatcherAndCloseImplNoLock();
404 void Dispatcher::StartSerialize(Channel* channel,
405 size_t* max_size,
406 size_t* max_platform_handles) {
407 DCHECK(channel);
408 DCHECK(max_size);
409 DCHECK(max_platform_handles);
410 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
411 DCHECK(!is_closed_);
412 StartSerializeImplNoLock(channel, max_size, max_platform_handles);
415 bool Dispatcher::EndSerializeAndClose(
416 Channel* channel,
417 void* destination,
418 size_t* actual_size,
419 std::vector<embedder::PlatformHandle>* platform_handles) {
420 DCHECK(channel);
421 DCHECK(actual_size);
422 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
423 DCHECK(!is_closed_);
425 // Like other |...Close()| methods, we mark ourselves as closed before calling
426 // the impl.
427 is_closed_ = true;
428 // No need to cancel waiters: we shouldn't have any (and shouldn't be in
429 // |Core|'s handle table.
431 #if !defined(NDEBUG)
432 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
433 // isn't actually needed, but we need to satisfy assertions (which we don't
434 // want to remove or weaken).
435 base::AutoLock locker(lock_);
436 #endif
438 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size,
439 platform_handles);
442 // DispatcherTransport ---------------------------------------------------------
444 void DispatcherTransport::End() {
445 DCHECK(dispatcher_);
446 dispatcher_->lock_.Release();
447 dispatcher_ = NULL;
450 } // namespace system
451 } // namespace mojo