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/data_pipe_consumer_dispatcher.h"
      6 
      7 #include "base/logging.h"
      8 #include "mojo/system/data_pipe.h"
      9 #include "mojo/system/memory.h"
     10 
     11 namespace mojo {
     12 namespace system {
     13 
     14 DataPipeConsumerDispatcher::DataPipeConsumerDispatcher() {
     15 }
     16 
     17 void DataPipeConsumerDispatcher::Init(scoped_refptr<DataPipe> data_pipe) {
     18   DCHECK(data_pipe.get());
     19   data_pipe_ = data_pipe;
     20 }
     21 
     22 DataPipeConsumerDispatcher::~DataPipeConsumerDispatcher() {
     23   // |Close()|/|CloseImplNoLock()| should have taken care of the pipe.
     24   DCHECK(!data_pipe_.get());
     25 }
     26 
     27 void DataPipeConsumerDispatcher::CancelAllWaitersNoLock() {
     28   lock().AssertAcquired();
     29   data_pipe_->ConsumerCancelAllWaiters();
     30 }
     31 
     32 MojoResult DataPipeConsumerDispatcher::CloseImplNoLock() {
     33   lock().AssertAcquired();
     34   data_pipe_->ConsumerClose();
     35   data_pipe_ = NULL;
     36   return MOJO_RESULT_OK;
     37 }
     38 
     39 MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock(
     40     void* elements,
     41     uint32_t* num_elements,
     42     MojoReadDataFlags flags) {
     43   lock().AssertAcquired();
     44 
     45   if (!VerifyUserPointer<uint32_t>(num_elements, 1))
     46     return MOJO_RESULT_INVALID_ARGUMENT;
     47   // These flags are mutally exclusive.
     48   if ((flags & MOJO_READ_DATA_FLAG_DISCARD) &&
     49       (flags & MOJO_READ_DATA_FLAG_QUERY))
     50     return MOJO_RESULT_INVALID_ARGUMENT;
     51   if ((flags & MOJO_READ_DATA_FLAG_DISCARD) ||
     52       (flags & MOJO_READ_DATA_FLAG_QUERY)) {
     53     DVLOG_IF(2, elements) << "Discard/query mode: ignoring non-null |elements|";
     54     elements = NULL;  // Null it out for safety.
     55   } else {
     56     // Only verify |elements| if we're neither discarding nor querying.
     57     if (!VerifyUserPointerForSize(elements, data_pipe_->element_size(),
     58                                   *num_elements))
     59       return MOJO_RESULT_INVALID_ARGUMENT;
     60   }
     61 
     62   return data_pipe_->ConsumerReadData(elements, num_elements, flags);
     63 }
     64 
     65 MojoResult DataPipeConsumerDispatcher::BeginReadDataImplNoLock(
     66     const void** buffer,
     67     uint32_t* buffer_num_elements,
     68     MojoReadDataFlags flags) {
     69   lock().AssertAcquired();
     70 
     71   if (!VerifyUserPointer<const void*>(buffer, 1))
     72     return MOJO_RESULT_INVALID_ARGUMENT;
     73   if (!VerifyUserPointer<uint32_t>(buffer_num_elements, 1))
     74     return MOJO_RESULT_INVALID_ARGUMENT;
     75   // These flags may not be used in two-phase mode.
     76   if ((flags & MOJO_READ_DATA_FLAG_DISCARD) ||
     77       (flags & MOJO_READ_DATA_FLAG_QUERY))
     78     return MOJO_RESULT_INVALID_ARGUMENT;
     79 
     80   return data_pipe_->ConsumerBeginReadData(buffer, buffer_num_elements, flags);
     81 }
     82 
     83 MojoResult DataPipeConsumerDispatcher::EndReadDataImplNoLock(
     84     uint32_t num_elements_read) {
     85   lock().AssertAcquired();
     86 
     87   return data_pipe_->ConsumerEndReadData(num_elements_read);
     88 }
     89 
     90 MojoResult DataPipeConsumerDispatcher::AddWaiterImplNoLock(
     91     Waiter* waiter,
     92     MojoWaitFlags flags,
     93     MojoResult wake_result) {
     94   lock().AssertAcquired();
     95   return data_pipe_->ConsumerAddWaiter(waiter, flags, wake_result);
     96 }
     97 
     98 void DataPipeConsumerDispatcher::RemoveWaiterImplNoLock(Waiter* waiter) {
     99   lock().AssertAcquired();
    100   data_pipe_->ConsumerRemoveWaiter(waiter);
    101 }
    102 
    103 scoped_refptr<Dispatcher>
    104 DataPipeConsumerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
    105   lock().AssertAcquired();
    106 
    107   scoped_refptr<DataPipeConsumerDispatcher> rv =
    108       new DataPipeConsumerDispatcher();
    109   rv->Init(data_pipe_);
    110   data_pipe_ = NULL;
    111   return scoped_refptr<Dispatcher>(rv.get());
    112 }
    113 
    114 }  // namespace system
    115 }  // namespace mojo
    116