Index: third_party/mojo/src/mojo/edk/system/data_pipe.cc |
diff --git a/third_party/mojo/src/mojo/edk/system/data_pipe.cc b/third_party/mojo/src/mojo/edk/system/data_pipe.cc |
index 2f433bdf9a5cd9eb91638a4647868124d1ca40df..d5e9db95266b49f20ac2f308314258895f02b190 100644 |
--- a/third_party/mojo/src/mojo/edk/system/data_pipe.cc |
+++ b/third_party/mojo/src/mojo/edk/system/data_pipe.cc |
@@ -12,6 +12,8 @@ |
#include "base/logging.h" |
#include "mojo/edk/system/awakable_list.h" |
#include "mojo/edk/system/configuration.h" |
+#include "mojo/edk/system/data_pipe_impl.h" |
+#include "mojo/edk/system/local_data_pipe_impl.h" |
#include "mojo/edk/system/memory.h" |
#include "mojo/edk/system/options_validation.h" |
@@ -83,6 +85,13 @@ MojoResult DataPipe::ValidateCreateOptions( |
return MOJO_RESULT_OK; |
} |
+// static |
+DataPipe* DataPipe::CreateLocal( |
+ const MojoCreateDataPipeOptions& validated_options) { |
+ return new DataPipe(true, true, validated_options, |
+ make_scoped_ptr(new LocalDataPipeImpl())); |
+} |
+ |
void DataPipe::ProducerCancelAllAwakables() { |
base::AutoLock locker(lock_); |
DCHECK(has_local_producer_no_lock()); |
@@ -91,17 +100,7 @@ void DataPipe::ProducerCancelAllAwakables() { |
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()); |
+ ProducerCloseNoLock(); |
} |
MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements, |
@@ -117,7 +116,7 @@ MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements, |
// 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) |
+ if (max_num_bytes_to_write % element_num_bytes() != 0) |
return MOJO_RESULT_INVALID_ARGUMENT; |
if (max_num_bytes_to_write == 0) |
@@ -126,11 +125,11 @@ MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements, |
uint32_t min_num_bytes_to_write = all_or_none ? max_num_bytes_to_write : 0; |
HandleSignalsState old_consumer_state = |
- ConsumerGetHandleSignalsStateImplNoLock(); |
- MojoResult rv = ProducerWriteDataImplNoLock( |
+ impl_->ConsumerGetHandleSignalsState(); |
+ MojoResult rv = impl_->ProducerWriteData( |
elements, num_bytes, max_num_bytes_to_write, min_num_bytes_to_write); |
HandleSignalsState new_consumer_state = |
- ConsumerGetHandleSignalsStateImplNoLock(); |
+ impl_->ConsumerGetHandleSignalsState(); |
if (!new_consumer_state.equals(old_consumer_state)) |
AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
return rv; |
@@ -151,12 +150,12 @@ MojoResult DataPipe::ProducerBeginWriteData( |
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) |
+ 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); |
+ MojoResult rv = impl_->ProducerBeginWriteData(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 |
@@ -177,25 +176,25 @@ MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) { |
// consumer has been closed. |
HandleSignalsState old_consumer_state = |
- ConsumerGetHandleSignalsStateImplNoLock(); |
+ impl_->ConsumerGetHandleSignalsState(); |
MojoResult rv; |
if (num_bytes_written > producer_two_phase_max_num_bytes_written_ || |
- num_bytes_written % element_num_bytes_ != 0) { |
+ 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); |
+ rv = impl_->ProducerEndWriteData(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(); |
+ impl_->ProducerGetHandleSignalsState(); |
if (new_producer_state.satisfies(MOJO_HANDLE_SIGNAL_WRITABLE)) |
AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
HandleSignalsState new_consumer_state = |
- ConsumerGetHandleSignalsStateImplNoLock(); |
+ impl_->ConsumerGetHandleSignalsState(); |
if (!new_consumer_state.equals(old_consumer_state)) |
AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
return rv; |
@@ -204,7 +203,7 @@ MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) { |
HandleSignalsState DataPipe::ProducerGetHandleSignalsState() { |
base::AutoLock locker(lock_); |
DCHECK(has_local_producer_no_lock()); |
- return ProducerGetHandleSignalsStateImplNoLock(); |
+ return impl_->ProducerGetHandleSignalsState(); |
} |
MojoResult DataPipe::ProducerAddAwakable(Awakable* awakable, |
@@ -214,7 +213,7 @@ MojoResult DataPipe::ProducerAddAwakable(Awakable* awakable, |
base::AutoLock locker(lock_); |
DCHECK(has_local_producer_no_lock()); |
- HandleSignalsState producer_state = ProducerGetHandleSignalsStateImplNoLock(); |
+ HandleSignalsState producer_state = impl_->ProducerGetHandleSignalsState(); |
if (producer_state.satisfies(signals)) { |
if (signals_state) |
*signals_state = producer_state; |
@@ -236,7 +235,26 @@ void DataPipe::ProducerRemoveAwakable(Awakable* awakable, |
DCHECK(has_local_producer_no_lock()); |
producer_awakable_list_->Remove(awakable); |
if (signals_state) |
- *signals_state = ProducerGetHandleSignalsStateImplNoLock(); |
+ *signals_state = impl_->ProducerGetHandleSignalsState(); |
+} |
+ |
+void DataPipe::ProducerStartSerialize(Channel* channel, |
+ size_t* max_size, |
+ size_t* max_platform_handles) { |
+ base::AutoLock locker(lock_); |
+ DCHECK(has_local_producer_no_lock()); |
+ impl_->ProducerStartSerialize(channel, max_size, max_platform_handles); |
+} |
+ |
+bool DataPipe::ProducerEndSerialize( |
+ Channel* channel, |
+ void* destination, |
+ size_t* actual_size, |
+ embedder::PlatformHandleVector* platform_handles) { |
+ base::AutoLock locker(lock_); |
+ DCHECK(has_local_producer_no_lock()); |
+ return impl_->ProducerEndSerialize(channel, destination, actual_size, |
+ platform_handles); |
} |
bool DataPipe::ProducerIsBusy() const { |
@@ -252,17 +270,7 @@ void DataPipe::ConsumerCancelAllAwakables() { |
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()); |
+ ConsumerCloseNoLock(); |
} |
MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, |
@@ -276,7 +284,7 @@ MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, |
return MOJO_RESULT_BUSY; |
uint32_t max_num_bytes_to_read = num_bytes.Get(); |
- if (max_num_bytes_to_read % element_num_bytes_ != 0) |
+ if (max_num_bytes_to_read % element_num_bytes() != 0) |
return MOJO_RESULT_INVALID_ARGUMENT; |
if (max_num_bytes_to_read == 0) |
@@ -285,11 +293,11 @@ MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, |
uint32_t min_num_bytes_to_read = all_or_none ? max_num_bytes_to_read : 0; |
HandleSignalsState old_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
- MojoResult rv = ConsumerReadDataImplNoLock( |
+ impl_->ProducerGetHandleSignalsState(); |
+ MojoResult rv = impl_->ConsumerReadData( |
elements, num_bytes, max_num_bytes_to_read, min_num_bytes_to_read, peek); |
HandleSignalsState new_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
+ impl_->ProducerGetHandleSignalsState(); |
if (!new_producer_state.equals(old_producer_state)) |
AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
return rv; |
@@ -304,7 +312,7 @@ MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes, |
return MOJO_RESULT_BUSY; |
uint32_t max_num_bytes_to_discard = num_bytes.Get(); |
- if (max_num_bytes_to_discard % element_num_bytes_ != 0) |
+ if (max_num_bytes_to_discard % element_num_bytes() != 0) |
return MOJO_RESULT_INVALID_ARGUMENT; |
if (max_num_bytes_to_discard == 0) |
@@ -314,11 +322,11 @@ MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes, |
all_or_none ? max_num_bytes_to_discard : 0; |
HandleSignalsState old_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
- MojoResult rv = ConsumerDiscardDataImplNoLock( |
+ impl_->ProducerGetHandleSignalsState(); |
+ MojoResult rv = impl_->ConsumerDiscardData( |
num_bytes, max_num_bytes_to_discard, min_num_bytes_to_discard); |
HandleSignalsState new_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
+ impl_->ProducerGetHandleSignalsState(); |
if (!new_producer_state.equals(old_producer_state)) |
AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
return rv; |
@@ -332,7 +340,7 @@ MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) { |
return MOJO_RESULT_BUSY; |
// Note: Don't need to validate |*num_bytes| for query. |
- return ConsumerQueryDataImplNoLock(num_bytes); |
+ return impl_->ConsumerQueryData(num_bytes); |
} |
MojoResult DataPipe::ConsumerBeginReadData( |
@@ -348,12 +356,12 @@ MojoResult DataPipe::ConsumerBeginReadData( |
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) |
+ 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); |
+ MojoResult rv = impl_->ConsumerBeginReadData(buffer, buffer_num_bytes, |
+ min_num_bytes_to_read); |
if (rv != MOJO_RESULT_OK) |
return rv; |
DCHECK(consumer_in_two_phase_read_no_lock()); |
@@ -368,25 +376,25 @@ MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) { |
return MOJO_RESULT_FAILED_PRECONDITION; |
HandleSignalsState old_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
+ impl_->ProducerGetHandleSignalsState(); |
MojoResult rv; |
if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ || |
- num_bytes_read % element_num_bytes_ != 0) { |
+ 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); |
+ rv = impl_->ConsumerEndReadData(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(); |
+ impl_->ConsumerGetHandleSignalsState(); |
if (new_consumer_state.satisfies(MOJO_HANDLE_SIGNAL_READABLE)) |
AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
HandleSignalsState new_producer_state = |
- ProducerGetHandleSignalsStateImplNoLock(); |
+ impl_->ProducerGetHandleSignalsState(); |
if (!new_producer_state.equals(old_producer_state)) |
AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
return rv; |
@@ -395,7 +403,7 @@ MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) { |
HandleSignalsState DataPipe::ConsumerGetHandleSignalsState() { |
base::AutoLock locker(lock_); |
DCHECK(has_local_consumer_no_lock()); |
- return ConsumerGetHandleSignalsStateImplNoLock(); |
+ return impl_->ConsumerGetHandleSignalsState(); |
} |
MojoResult DataPipe::ConsumerAddAwakable(Awakable* awakable, |
@@ -405,7 +413,7 @@ MojoResult DataPipe::ConsumerAddAwakable(Awakable* awakable, |
base::AutoLock locker(lock_); |
DCHECK(has_local_consumer_no_lock()); |
- HandleSignalsState consumer_state = ConsumerGetHandleSignalsStateImplNoLock(); |
+ HandleSignalsState consumer_state = impl_->ConsumerGetHandleSignalsState(); |
if (consumer_state.satisfies(signals)) { |
if (signals_state) |
*signals_state = consumer_state; |
@@ -427,7 +435,26 @@ void DataPipe::ConsumerRemoveAwakable(Awakable* awakable, |
DCHECK(has_local_consumer_no_lock()); |
consumer_awakable_list_->Remove(awakable); |
if (signals_state) |
- *signals_state = ConsumerGetHandleSignalsStateImplNoLock(); |
+ *signals_state = impl_->ConsumerGetHandleSignalsState(); |
+} |
+ |
+void DataPipe::ConsumerStartSerialize(Channel* channel, |
+ size_t* max_size, |
+ size_t* max_platform_handles) { |
+ base::AutoLock locker(lock_); |
+ DCHECK(has_local_consumer_no_lock()); |
+ impl_->ConsumerStartSerialize(channel, max_size, max_platform_handles); |
+} |
+ |
+bool DataPipe::ConsumerEndSerialize( |
+ Channel* channel, |
+ void* destination, |
+ size_t* actual_size, |
+ embedder::PlatformHandleVector* platform_handles) { |
+ base::AutoLock locker(lock_); |
+ DCHECK(has_local_consumer_no_lock()); |
+ return impl_->ConsumerEndSerialize(channel, destination, actual_size, |
+ platform_handles); |
} |
bool DataPipe::ConsumerIsBusy() const { |
@@ -437,11 +464,9 @@ bool DataPipe::ConsumerIsBusy() const { |
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), |
+ const MojoCreateDataPipeOptions& validated_options, |
+ scoped_ptr<DataPipeImpl> impl) |
+ : validated_options_(validated_options), |
producer_open_(true), |
consumer_open_(true), |
producer_awakable_list_(has_local_producer ? new AwakableList() |
@@ -449,11 +474,16 @@ DataPipe::DataPipe(bool has_local_producer, |
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) { |
+ consumer_two_phase_max_num_bytes_read_(0), |
+ impl_(impl.Pass()) { |
+ impl_->set_owner(this); |
+ |
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
// Check that the passed in options actually are validated. |
MojoCreateDataPipeOptions unused = {0}; |
DCHECK_EQ(ValidateCreateOptions(MakeUserPointer(&validated_options), &unused), |
MOJO_RESULT_OK); |
+#endif // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
} |
DataPipe::~DataPipe() { |
@@ -463,6 +493,36 @@ DataPipe::~DataPipe() { |
DCHECK(!consumer_awakable_list_); |
} |
+void DataPipe::ProducerCloseNoLock() { |
+ lock_.AssertAcquired(); |
+ 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; |
+ impl_->ProducerClose(); |
+ AwakeConsumerAwakablesForStateChangeNoLock( |
+ impl_->ConsumerGetHandleSignalsState()); |
+} |
+ |
+void DataPipe::ConsumerCloseNoLock() { |
+ lock_.AssertAcquired(); |
+ 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; |
+ impl_->ConsumerClose(); |
+ AwakeProducerAwakablesForStateChangeNoLock( |
+ impl_->ProducerGetHandleSignalsState()); |
+} |
+ |
void DataPipe::AwakeProducerAwakablesForStateChangeNoLock( |
const HandleSignalsState& new_producer_state) { |
lock_.AssertAcquired(); |