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. 4 5 #include "mojo/system/message_pipe_dispatcher.h" 6 7 #include "base/logging.h" 8 #include "mojo/system/constants.h" 9 #include "mojo/system/memory.h" 10 #include "mojo/system/message_pipe.h" 11 12 namespace mojo { 13 namespace system { 14 15 const unsigned kInvalidPort = static_cast<unsigned>(-1); 16 17 MessagePipeDispatcher::MessagePipeDispatcher() 18 : port_(kInvalidPort) { 19 } 20 21 void MessagePipeDispatcher::Init(scoped_refptr<MessagePipe> message_pipe, 22 unsigned port) { 23 DCHECK(message_pipe.get()); 24 DCHECK(port == 0 || port == 1); 25 26 message_pipe_ = message_pipe; 27 port_ = port; 28 } 29 30 MessagePipeDispatcher::~MessagePipeDispatcher() { 31 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. 32 DCHECK(!message_pipe_.get()); 33 } 34 35 void MessagePipeDispatcher::CancelAllWaitersNoLock() { 36 lock().AssertAcquired(); 37 message_pipe_->CancelAllWaiters(port_); 38 } 39 40 MojoResult MessagePipeDispatcher::CloseImplNoLock() { 41 lock().AssertAcquired(); 42 message_pipe_->Close(port_); 43 message_pipe_ = NULL; 44 port_ = kInvalidPort; 45 return MOJO_RESULT_OK; 46 } 47 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)); 54 55 lock().AssertAcquired(); 56 57 if (!VerifyUserPointer<void>(bytes, num_bytes)) 58 return MOJO_RESULT_INVALID_ARGUMENT; 59 if (num_bytes > kMaxMessageNumBytes) 60 return MOJO_RESULT_RESOURCE_EXHAUSTED; 61 62 return message_pipe_->WriteMessage(port_, 63 bytes, num_bytes, 64 dispatchers, 65 flags); 66 } 67 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(); 74 75 if (num_bytes) { 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; 80 } 81 82 return message_pipe_->ReadMessage(port_, 83 bytes, num_bytes, 84 dispatchers, num_dispatchers, 85 flags); 86 } 87 88 MojoResult MessagePipeDispatcher::AddWaiterImplNoLock(Waiter* waiter, 89 MojoWaitFlags flags, 90 MojoResult wake_result) { 91 lock().AssertAcquired(); 92 return message_pipe_->AddWaiter(port_, waiter, flags, wake_result); 93 } 94 95 void MessagePipeDispatcher::RemoveWaiterImplNoLock(Waiter* waiter) { 96 lock().AssertAcquired(); 97 message_pipe_->RemoveWaiter(port_, waiter); 98 } 99 100 scoped_refptr<Dispatcher> 101 MessagePipeDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { 102 lock().AssertAcquired(); 103 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()); 109 } 110 111 } // namespace system 112 } // namespace mojo 113