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/message_pipe_dispatcher.h"
7 #include "base/logging.h"
8 #include "mojo/system/constants.h"
9 #include "mojo/system/memory.h"
10 #include "mojo/system/message_pipe.h"
15 const unsigned kInvalidPort = static_cast<unsigned>(-1);
17 MessagePipeDispatcher::MessagePipeDispatcher()
18 : port_(kInvalidPort) {
21 void MessagePipeDispatcher::Init(scoped_refptr<MessagePipe> message_pipe,
23 DCHECK(message_pipe.get());
24 DCHECK(port == 0 || port == 1);
26 message_pipe_ = message_pipe;
30 MessagePipeDispatcher::~MessagePipeDispatcher() {
31 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe.
32 DCHECK(!message_pipe_.get());
35 void MessagePipeDispatcher::CancelAllWaitersNoLock() {
36 lock().AssertAcquired();
37 message_pipe_->CancelAllWaiters(port_);
40 MojoResult MessagePipeDispatcher::CloseImplNoLock() {
41 lock().AssertAcquired();
42 message_pipe_->Close(port_);
45 return MOJO_RESULT_OK;
48 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock(
49 const void* bytes, uint32_t num_bytes,
50 const std::vector<Dispatcher*>* dispatchers,
51 MojoWriteMessageFlags flags) {
52 DCHECK(!dispatchers || (dispatchers->size() > 0 &&
53 dispatchers->size() <= kMaxMessageNumHandles));
55 lock().AssertAcquired();
57 if (!VerifyUserPointer<void>(bytes, num_bytes))
58 return MOJO_RESULT_INVALID_ARGUMENT;
59 if (num_bytes > kMaxMessageNumBytes)
60 return MOJO_RESULT_RESOURCE_EXHAUSTED;
62 return message_pipe_->WriteMessage(port_,
68 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock(
69 void* bytes, uint32_t* num_bytes,
70 std::vector<scoped_refptr<Dispatcher> >* dispatchers,
71 uint32_t* num_dispatchers,
72 MojoReadMessageFlags flags) {
73 lock().AssertAcquired();
76 if (!VerifyUserPointer<uint32_t>(num_bytes, 1))
77 return MOJO_RESULT_INVALID_ARGUMENT;
78 if (!VerifyUserPointer<void>(bytes, *num_bytes))
79 return MOJO_RESULT_INVALID_ARGUMENT;
82 return message_pipe_->ReadMessage(port_,
84 dispatchers, num_dispatchers,
88 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock(Waiter* waiter,
90 MojoResult wake_result) {
91 lock().AssertAcquired();
92 return message_pipe_->AddWaiter(port_, waiter, flags, wake_result);
95 void MessagePipeDispatcher::RemoveWaiterImplNoLock(Waiter* waiter) {
96 lock().AssertAcquired();
97 message_pipe_->RemoveWaiter(port_, waiter);
100 scoped_refptr<Dispatcher>
101 MessagePipeDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
102 lock().AssertAcquired();
104 scoped_refptr<MessagePipeDispatcher> rv = new MessagePipeDispatcher();
105 rv->Init(message_pipe_, port_);
106 message_pipe_ = NULL;
107 port_ = kInvalidPort;
108 return scoped_refptr<Dispatcher>(rv.get());
111 } // namespace system