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