• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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