Home | History | Annotate | Download | only in system
      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