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
MessagePipeDispatcher()17 MessagePipeDispatcher::MessagePipeDispatcher()
18 : port_(kInvalidPort) {
19 }
20
Init(scoped_refptr<MessagePipe> message_pipe,unsigned port)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
~MessagePipeDispatcher()30 MessagePipeDispatcher::~MessagePipeDispatcher() {
31 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe.
32 DCHECK(!message_pipe_.get());
33 }
34
CancelAllWaitersNoLock()35 void MessagePipeDispatcher::CancelAllWaitersNoLock() {
36 lock().AssertAcquired();
37 message_pipe_->CancelAllWaiters(port_);
38 }
39
CloseImplNoLock()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
WriteMessageImplNoLock(const void * bytes,uint32_t num_bytes,const std::vector<Dispatcher * > * dispatchers,MojoWriteMessageFlags flags)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
ReadMessageImplNoLock(void * bytes,uint32_t * num_bytes,std::vector<scoped_refptr<Dispatcher>> * dispatchers,uint32_t * num_dispatchers,MojoReadMessageFlags flags)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
AddWaiterImplNoLock(Waiter * waiter,MojoWaitFlags flags,MojoResult wake_result)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
RemoveWaiterImplNoLock(Waiter * waiter)95 void MessagePipeDispatcher::RemoveWaiterImplNoLock(Waiter* waiter) {
96 lock().AssertAcquired();
97 message_pipe_->RemoveWaiter(port_, waiter);
98 }
99
100 scoped_refptr<Dispatcher>
CreateEquivalentDispatcherAndCloseImplNoLock()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