Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Unified Diff: mojo/edk/system/data_pipe.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/edk/system/data_pipe.h ('k') | mojo/edk/system/data_pipe_consumer_dispatcher.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/edk/system/data_pipe.cc
diff --git a/mojo/edk/system/data_pipe.cc b/mojo/edk/system/data_pipe.cc
deleted file mode 100644
index 2f433bdf9a5cd9eb91638a4647868124d1ca40df..0000000000000000000000000000000000000000
--- a/mojo/edk/system/data_pipe.cc
+++ /dev/null
@@ -1,483 +0,0 @@
-// 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/edk/system/data_pipe.h"
-
-#include <string.h>
-
-#include <algorithm>
-#include <limits>
-
-#include "base/logging.h"
-#include "mojo/edk/system/awakable_list.h"
-#include "mojo/edk/system/configuration.h"
-#include "mojo/edk/system/memory.h"
-#include "mojo/edk/system/options_validation.h"
-
-namespace mojo {
-namespace system {
-
-// static
-MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() {
- MojoCreateDataPipeOptions result = {
- static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
- 1u,
- static_cast<uint32_t>(
- GetConfiguration().default_data_pipe_capacity_bytes)};
- return result;
-}
-
-// static
-MojoResult DataPipe::ValidateCreateOptions(
- UserPointer<const MojoCreateDataPipeOptions> in_options,
- MojoCreateDataPipeOptions* out_options) {
- const MojoCreateDataPipeOptionsFlags kKnownFlags =
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD;
-
- *out_options = GetDefaultCreateOptions();
- if (in_options.IsNull())
- return MOJO_RESULT_OK;
-
- UserOptionsReader<MojoCreateDataPipeOptions> reader(in_options);
- if (!reader.is_valid())
- return MOJO_RESULT_INVALID_ARGUMENT;
-
- if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, flags, reader))
- return MOJO_RESULT_OK;
- if ((reader.options().flags & ~kKnownFlags))
- return MOJO_RESULT_UNIMPLEMENTED;
- out_options->flags = reader.options().flags;
-
- // Checks for fields beyond |flags|:
-
- if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, element_num_bytes,
- reader))
- return MOJO_RESULT_OK;
- if (reader.options().element_num_bytes == 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
- out_options->element_num_bytes = reader.options().element_num_bytes;
-
- if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, capacity_num_bytes,
- reader) ||
- reader.options().capacity_num_bytes == 0) {
- // Round the default capacity down to a multiple of the element size (but at
- // least one element).
- size_t default_data_pipe_capacity_bytes =
- GetConfiguration().default_data_pipe_capacity_bytes;
- out_options->capacity_num_bytes =
- std::max(static_cast<uint32_t>(default_data_pipe_capacity_bytes -
- (default_data_pipe_capacity_bytes %
- out_options->element_num_bytes)),
- out_options->element_num_bytes);
- return MOJO_RESULT_OK;
- }
- if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
- if (reader.options().capacity_num_bytes >
- GetConfiguration().max_data_pipe_capacity_bytes)
- return MOJO_RESULT_RESOURCE_EXHAUSTED;
- out_options->capacity_num_bytes = reader.options().capacity_num_bytes;
-
- return MOJO_RESULT_OK;
-}
-
-void DataPipe::ProducerCancelAllAwakables() {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
- producer_awakable_list_->CancelAll();
-}
-
-void DataPipe::ProducerClose() {
- base::AutoLock locker(lock_);
- DCHECK(producer_open_);
- producer_open_ = false;
- DCHECK(has_local_producer_no_lock());
- producer_awakable_list_.reset();
- // Not a bug, except possibly in "user" code.
- DVLOG_IF(2, producer_in_two_phase_write_no_lock())
- << "Producer closed with active two-phase write";
- producer_two_phase_max_num_bytes_written_ = 0;
- ProducerCloseImplNoLock();
- AwakeConsumerAwakablesForStateChangeNoLock(
- ConsumerGetHandleSignalsStateImplNoLock());
-}
-
-MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements,
- UserPointer<uint32_t> num_bytes,
- bool all_or_none) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
-
- if (producer_in_two_phase_write_no_lock())
- return MOJO_RESULT_BUSY;
- if (!consumer_open_no_lock())
- return MOJO_RESULT_FAILED_PRECONDITION;
-
- // Returning "busy" takes priority over "invalid argument".
- uint32_t max_num_bytes_to_write = num_bytes.Get();
- if (max_num_bytes_to_write % element_num_bytes_ != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
-
- if (max_num_bytes_to_write == 0)
- return MOJO_RESULT_OK; // Nothing to do.
-
- uint32_t min_num_bytes_to_write = all_or_none ? max_num_bytes_to_write : 0;
-
- HandleSignalsState old_consumer_state =
- ConsumerGetHandleSignalsStateImplNoLock();
- MojoResult rv = ProducerWriteDataImplNoLock(
- elements, num_bytes, max_num_bytes_to_write, min_num_bytes_to_write);
- HandleSignalsState new_consumer_state =
- ConsumerGetHandleSignalsStateImplNoLock();
- if (!new_consumer_state.equals(old_consumer_state))
- AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state);
- return rv;
-}
-
-MojoResult DataPipe::ProducerBeginWriteData(
- UserPointer<void*> buffer,
- UserPointer<uint32_t> buffer_num_bytes,
- bool all_or_none) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
-
- if (producer_in_two_phase_write_no_lock())
- return MOJO_RESULT_BUSY;
- if (!consumer_open_no_lock())
- return MOJO_RESULT_FAILED_PRECONDITION;
-
- uint32_t min_num_bytes_to_write = 0;
- if (all_or_none) {
- min_num_bytes_to_write = buffer_num_bytes.Get();
- if (min_num_bytes_to_write % element_num_bytes_ != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
- }
-
- MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes,
- min_num_bytes_to_write);
- if (rv != MOJO_RESULT_OK)
- return rv;
- // Note: No need to awake producer awakables, even though we're going from
- // writable to non-writable (since you can't wait on non-writability).
- // Similarly, though this may have discarded data (in "may discard" mode),
- // making it non-readable, there's still no need to awake consumer awakables.
- DCHECK(producer_in_two_phase_write_no_lock());
- return MOJO_RESULT_OK;
-}
-
-MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
-
- if (!producer_in_two_phase_write_no_lock())
- return MOJO_RESULT_FAILED_PRECONDITION;
- // Note: Allow successful completion of the two-phase write even if the
- // consumer has been closed.
-
- HandleSignalsState old_consumer_state =
- ConsumerGetHandleSignalsStateImplNoLock();
- MojoResult rv;
- if (num_bytes_written > producer_two_phase_max_num_bytes_written_ ||
- num_bytes_written % element_num_bytes_ != 0) {
- rv = MOJO_RESULT_INVALID_ARGUMENT;
- producer_two_phase_max_num_bytes_written_ = 0;
- } else {
- rv = ProducerEndWriteDataImplNoLock(num_bytes_written);
- }
- // Two-phase write ended even on failure.
- DCHECK(!producer_in_two_phase_write_no_lock());
- // If we're now writable, we *became* writable (since we weren't writable
- // during the two-phase write), so awake producer awakables.
- HandleSignalsState new_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- if (new_producer_state.satisfies(MOJO_HANDLE_SIGNAL_WRITABLE))
- AwakeProducerAwakablesForStateChangeNoLock(new_producer_state);
- HandleSignalsState new_consumer_state =
- ConsumerGetHandleSignalsStateImplNoLock();
- if (!new_consumer_state.equals(old_consumer_state))
- AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state);
- return rv;
-}
-
-HandleSignalsState DataPipe::ProducerGetHandleSignalsState() {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
- return ProducerGetHandleSignalsStateImplNoLock();
-}
-
-MojoResult DataPipe::ProducerAddAwakable(Awakable* awakable,
- MojoHandleSignals signals,
- uint32_t context,
- HandleSignalsState* signals_state) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
-
- HandleSignalsState producer_state = ProducerGetHandleSignalsStateImplNoLock();
- if (producer_state.satisfies(signals)) {
- if (signals_state)
- *signals_state = producer_state;
- return MOJO_RESULT_ALREADY_EXISTS;
- }
- if (!producer_state.can_satisfy(signals)) {
- if (signals_state)
- *signals_state = producer_state;
- return MOJO_RESULT_FAILED_PRECONDITION;
- }
-
- producer_awakable_list_->Add(awakable, signals, context);
- return MOJO_RESULT_OK;
-}
-
-void DataPipe::ProducerRemoveAwakable(Awakable* awakable,
- HandleSignalsState* signals_state) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_producer_no_lock());
- producer_awakable_list_->Remove(awakable);
- if (signals_state)
- *signals_state = ProducerGetHandleSignalsStateImplNoLock();
-}
-
-bool DataPipe::ProducerIsBusy() const {
- base::AutoLock locker(lock_);
- return producer_in_two_phase_write_no_lock();
-}
-
-void DataPipe::ConsumerCancelAllAwakables() {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
- consumer_awakable_list_->CancelAll();
-}
-
-void DataPipe::ConsumerClose() {
- base::AutoLock locker(lock_);
- DCHECK(consumer_open_);
- consumer_open_ = false;
- DCHECK(has_local_consumer_no_lock());
- consumer_awakable_list_.reset();
- // Not a bug, except possibly in "user" code.
- DVLOG_IF(2, consumer_in_two_phase_read_no_lock())
- << "Consumer closed with active two-phase read";
- consumer_two_phase_max_num_bytes_read_ = 0;
- ConsumerCloseImplNoLock();
- AwakeProducerAwakablesForStateChangeNoLock(
- ProducerGetHandleSignalsStateImplNoLock());
-}
-
-MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements,
- UserPointer<uint32_t> num_bytes,
- bool all_or_none,
- bool peek) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- if (consumer_in_two_phase_read_no_lock())
- return MOJO_RESULT_BUSY;
-
- uint32_t max_num_bytes_to_read = num_bytes.Get();
- if (max_num_bytes_to_read % element_num_bytes_ != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
-
- if (max_num_bytes_to_read == 0)
- return MOJO_RESULT_OK; // Nothing to do.
-
- uint32_t min_num_bytes_to_read = all_or_none ? max_num_bytes_to_read : 0;
-
- HandleSignalsState old_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- MojoResult rv = ConsumerReadDataImplNoLock(
- elements, num_bytes, max_num_bytes_to_read, min_num_bytes_to_read, peek);
- HandleSignalsState new_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- if (!new_producer_state.equals(old_producer_state))
- AwakeProducerAwakablesForStateChangeNoLock(new_producer_state);
- return rv;
-}
-
-MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes,
- bool all_or_none) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- if (consumer_in_two_phase_read_no_lock())
- return MOJO_RESULT_BUSY;
-
- uint32_t max_num_bytes_to_discard = num_bytes.Get();
- if (max_num_bytes_to_discard % element_num_bytes_ != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
-
- if (max_num_bytes_to_discard == 0)
- return MOJO_RESULT_OK; // Nothing to do.
-
- uint32_t min_num_bytes_to_discard =
- all_or_none ? max_num_bytes_to_discard : 0;
-
- HandleSignalsState old_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- MojoResult rv = ConsumerDiscardDataImplNoLock(
- num_bytes, max_num_bytes_to_discard, min_num_bytes_to_discard);
- HandleSignalsState new_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- if (!new_producer_state.equals(old_producer_state))
- AwakeProducerAwakablesForStateChangeNoLock(new_producer_state);
- return rv;
-}
-
-MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- if (consumer_in_two_phase_read_no_lock())
- return MOJO_RESULT_BUSY;
-
- // Note: Don't need to validate |*num_bytes| for query.
- return ConsumerQueryDataImplNoLock(num_bytes);
-}
-
-MojoResult DataPipe::ConsumerBeginReadData(
- UserPointer<const void*> buffer,
- UserPointer<uint32_t> buffer_num_bytes,
- bool all_or_none) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- if (consumer_in_two_phase_read_no_lock())
- return MOJO_RESULT_BUSY;
-
- uint32_t min_num_bytes_to_read = 0;
- if (all_or_none) {
- min_num_bytes_to_read = buffer_num_bytes.Get();
- if (min_num_bytes_to_read % element_num_bytes_ != 0)
- return MOJO_RESULT_INVALID_ARGUMENT;
- }
-
- MojoResult rv = ConsumerBeginReadDataImplNoLock(buffer, buffer_num_bytes,
- min_num_bytes_to_read);
- if (rv != MOJO_RESULT_OK)
- return rv;
- DCHECK(consumer_in_two_phase_read_no_lock());
- return MOJO_RESULT_OK;
-}
-
-MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- if (!consumer_in_two_phase_read_no_lock())
- return MOJO_RESULT_FAILED_PRECONDITION;
-
- HandleSignalsState old_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- MojoResult rv;
- if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ ||
- num_bytes_read % element_num_bytes_ != 0) {
- rv = MOJO_RESULT_INVALID_ARGUMENT;
- consumer_two_phase_max_num_bytes_read_ = 0;
- } else {
- rv = ConsumerEndReadDataImplNoLock(num_bytes_read);
- }
- // Two-phase read ended even on failure.
- DCHECK(!consumer_in_two_phase_read_no_lock());
- // If we're now readable, we *became* readable (since we weren't readable
- // during the two-phase read), so awake consumer awakables.
- HandleSignalsState new_consumer_state =
- ConsumerGetHandleSignalsStateImplNoLock();
- if (new_consumer_state.satisfies(MOJO_HANDLE_SIGNAL_READABLE))
- AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state);
- HandleSignalsState new_producer_state =
- ProducerGetHandleSignalsStateImplNoLock();
- if (!new_producer_state.equals(old_producer_state))
- AwakeProducerAwakablesForStateChangeNoLock(new_producer_state);
- return rv;
-}
-
-HandleSignalsState DataPipe::ConsumerGetHandleSignalsState() {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
- return ConsumerGetHandleSignalsStateImplNoLock();
-}
-
-MojoResult DataPipe::ConsumerAddAwakable(Awakable* awakable,
- MojoHandleSignals signals,
- uint32_t context,
- HandleSignalsState* signals_state) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
-
- HandleSignalsState consumer_state = ConsumerGetHandleSignalsStateImplNoLock();
- if (consumer_state.satisfies(signals)) {
- if (signals_state)
- *signals_state = consumer_state;
- return MOJO_RESULT_ALREADY_EXISTS;
- }
- if (!consumer_state.can_satisfy(signals)) {
- if (signals_state)
- *signals_state = consumer_state;
- return MOJO_RESULT_FAILED_PRECONDITION;
- }
-
- consumer_awakable_list_->Add(awakable, signals, context);
- return MOJO_RESULT_OK;
-}
-
-void DataPipe::ConsumerRemoveAwakable(Awakable* awakable,
- HandleSignalsState* signals_state) {
- base::AutoLock locker(lock_);
- DCHECK(has_local_consumer_no_lock());
- consumer_awakable_list_->Remove(awakable);
- if (signals_state)
- *signals_state = ConsumerGetHandleSignalsStateImplNoLock();
-}
-
-bool DataPipe::ConsumerIsBusy() const {
- base::AutoLock locker(lock_);
- return consumer_in_two_phase_read_no_lock();
-}
-
-DataPipe::DataPipe(bool has_local_producer,
- bool has_local_consumer,
- const MojoCreateDataPipeOptions& validated_options)
- : may_discard_((validated_options.flags &
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)),
- element_num_bytes_(validated_options.element_num_bytes),
- capacity_num_bytes_(validated_options.capacity_num_bytes),
- producer_open_(true),
- consumer_open_(true),
- producer_awakable_list_(has_local_producer ? new AwakableList()
- : nullptr),
- consumer_awakable_list_(has_local_consumer ? new AwakableList()
- : nullptr),
- producer_two_phase_max_num_bytes_written_(0),
- consumer_two_phase_max_num_bytes_read_(0) {
- // Check that the passed in options actually are validated.
- MojoCreateDataPipeOptions unused = {0};
- DCHECK_EQ(ValidateCreateOptions(MakeUserPointer(&validated_options), &unused),
- MOJO_RESULT_OK);
-}
-
-DataPipe::~DataPipe() {
- DCHECK(!producer_open_);
- DCHECK(!consumer_open_);
- DCHECK(!producer_awakable_list_);
- DCHECK(!consumer_awakable_list_);
-}
-
-void DataPipe::AwakeProducerAwakablesForStateChangeNoLock(
- const HandleSignalsState& new_producer_state) {
- lock_.AssertAcquired();
- if (!has_local_producer_no_lock())
- return;
- producer_awakable_list_->AwakeForStateChange(new_producer_state);
-}
-
-void DataPipe::AwakeConsumerAwakablesForStateChangeNoLock(
- const HandleSignalsState& new_consumer_state) {
- lock_.AssertAcquired();
- if (!has_local_consumer_no_lock())
- return;
- consumer_awakable_list_->AwakeForStateChange(new_consumer_state);
-}
-
-} // namespace system
-} // namespace mojo
« no previous file with comments | « mojo/edk/system/data_pipe.h ('k') | mojo/edk/system/data_pipe_consumer_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698