diff options
Diffstat (limited to 'mojo/system/data_pipe_consumer_dispatcher.cc')
-rw-r--r-- | mojo/system/data_pipe_consumer_dispatcher.cc | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/mojo/system/data_pipe_consumer_dispatcher.cc b/mojo/system/data_pipe_consumer_dispatcher.cc new file mode 100644 index 0000000..f0fc451 --- /dev/null +++ b/mojo/system/data_pipe_consumer_dispatcher.cc @@ -0,0 +1,115 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/system/data_pipe_consumer_dispatcher.h" + +#include "base/logging.h" +#include "mojo/system/data_pipe.h" +#include "mojo/system/memory.h" + +namespace mojo { +namespace system { + +DataPipeConsumerDispatcher::DataPipeConsumerDispatcher() { +} + +void DataPipeConsumerDispatcher::Init(scoped_refptr<DataPipe> data_pipe) { + DCHECK(data_pipe.get()); + data_pipe_ = data_pipe; +} + +DataPipeConsumerDispatcher::~DataPipeConsumerDispatcher() { + // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. + DCHECK(!data_pipe_.get()); +} + +void DataPipeConsumerDispatcher::CancelAllWaitersNoLock() { + lock().AssertAcquired(); + data_pipe_->ConsumerCancelAllWaiters(); +} + +MojoResult DataPipeConsumerDispatcher::CloseImplNoLock() { + lock().AssertAcquired(); + data_pipe_->ConsumerClose(); + data_pipe_ = NULL; + return MOJO_RESULT_OK; +} + +MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock( + void* elements, + uint32_t* num_elements, + MojoReadDataFlags flags) { + lock().AssertAcquired(); + + if (!VerifyUserPointer<uint32_t>(num_elements, 1)) + return MOJO_RESULT_INVALID_ARGUMENT; + // These flags are mutally exclusive. + if ((flags & MOJO_READ_DATA_FLAG_DISCARD) && + (flags & MOJO_READ_DATA_FLAG_QUERY)) + return MOJO_RESULT_INVALID_ARGUMENT; + if ((flags & MOJO_READ_DATA_FLAG_DISCARD) || + (flags & MOJO_READ_DATA_FLAG_QUERY)) { + DVLOG_IF(2, elements) << "Discard/query mode: ignoring non-null |elements|"; + elements = NULL; // Null it out for safety. + } else { + // Only verify |elements| if we're neither discarding nor querying. + if (!VerifyUserPointerForSize(elements, data_pipe_->element_size(), + *num_elements)) + return MOJO_RESULT_INVALID_ARGUMENT; + } + + return data_pipe_->ConsumerReadData(elements, num_elements, flags); +} + +MojoResult DataPipeConsumerDispatcher::BeginReadDataImplNoLock( + const void** buffer, + uint32_t* buffer_num_elements, + MojoReadDataFlags flags) { + lock().AssertAcquired(); + + if (!VerifyUserPointer<const void*>(buffer, 1)) + return MOJO_RESULT_INVALID_ARGUMENT; + if (!VerifyUserPointer<uint32_t>(buffer_num_elements, 1)) + return MOJO_RESULT_INVALID_ARGUMENT; + // These flags may not be used in two-phase mode. + if ((flags & MOJO_READ_DATA_FLAG_DISCARD) || + (flags & MOJO_READ_DATA_FLAG_QUERY)) + return MOJO_RESULT_INVALID_ARGUMENT; + + return data_pipe_->ConsumerBeginReadData(buffer, buffer_num_elements, flags); +} + +MojoResult DataPipeConsumerDispatcher::EndReadDataImplNoLock( + uint32_t num_elements_read) { + lock().AssertAcquired(); + + return data_pipe_->ConsumerEndReadData(num_elements_read); +} + +MojoResult DataPipeConsumerDispatcher::AddWaiterImplNoLock( + Waiter* waiter, + MojoWaitFlags flags, + MojoResult wake_result) { + lock().AssertAcquired(); + return data_pipe_->ConsumerAddWaiter(waiter, flags, wake_result); +} + +void DataPipeConsumerDispatcher::RemoveWaiterImplNoLock(Waiter* waiter) { + lock().AssertAcquired(); + data_pipe_->ConsumerRemoveWaiter(waiter); +} + +scoped_refptr<Dispatcher> +DataPipeConsumerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { + lock().AssertAcquired(); + + scoped_refptr<DataPipeConsumerDispatcher> rv = + new DataPipeConsumerDispatcher(); + rv->Init(data_pipe_); + data_pipe_ = NULL; + return scoped_refptr<Dispatcher>(rv.get()); +} + +} // namespace system +} // namespace mojo |