Convert ReadData...() to use the new user pointer handling (see r285350).

R=darin@chromium.org

Review URL: https://codereview.chromium.org/417113010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285762 0039d316-1c4b-4281-b951-d872f2087c98
parent e79cec23
...@@ -395,8 +395,7 @@ MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, ...@@ -395,8 +395,7 @@ MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle,
if (!dispatcher) if (!dispatcher)
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
return dispatcher->ReadData(elements.GetPointerUnsafe(), return dispatcher->ReadData(elements, num_bytes, flags);
num_bytes.GetPointerUnsafe(), flags);
} }
MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle,
......
...@@ -108,8 +108,8 @@ class MockDispatcher : public Dispatcher { ...@@ -108,8 +108,8 @@ class MockDispatcher : public Dispatcher {
return MOJO_RESULT_UNIMPLEMENTED; return MOJO_RESULT_UNIMPLEMENTED;
} }
virtual MojoResult ReadDataImplNoLock(void* /*elements*/, virtual MojoResult ReadDataImplNoLock(UserPointer<void> /*elements*/,
uint32_t* /*num_bytes*/, UserPointer<uint32_t> /*num_bytes*/,
MojoReadDataFlags /*flags*/) OVERRIDE { MojoReadDataFlags /*flags*/) OVERRIDE {
info_->IncrementReadDataCallCount(); info_->IncrementReadDataCallCount();
lock().AssertAcquired(); lock().AssertAcquired();
......
...@@ -230,8 +230,8 @@ void DataPipe::ConsumerClose() { ...@@ -230,8 +230,8 @@ void DataPipe::ConsumerClose() {
ProducerGetHandleSignalsStateNoLock()); ProducerGetHandleSignalsStateNoLock());
} }
MojoResult DataPipe::ConsumerReadData(void* elements, MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
bool all_or_none) { bool all_or_none) {
base::AutoLock locker(lock_); base::AutoLock locker(lock_);
DCHECK(has_local_consumer_no_lock()); DCHECK(has_local_consumer_no_lock());
...@@ -239,21 +239,26 @@ MojoResult DataPipe::ConsumerReadData(void* elements, ...@@ -239,21 +239,26 @@ MojoResult DataPipe::ConsumerReadData(void* elements,
if (consumer_in_two_phase_read_no_lock()) if (consumer_in_two_phase_read_no_lock())
return MOJO_RESULT_BUSY; return MOJO_RESULT_BUSY;
if (*num_bytes % element_num_bytes_ != 0) 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; return MOJO_RESULT_INVALID_ARGUMENT;
if (*num_bytes == 0) if (max_num_bytes_to_read == 0)
return MOJO_RESULT_OK; // Nothing to do. 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 = ProducerGetHandleSignalsStateNoLock(); HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock();
MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none); MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes,
max_num_bytes_to_read,
min_num_bytes_to_read);
HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock();
if (!new_producer_state.equals(old_producer_state)) if (!new_producer_state.equals(old_producer_state))
AwakeProducerWaitersForStateChangeNoLock(new_producer_state); AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
return rv; return rv;
} }
MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes, MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes,
bool all_or_none) { bool all_or_none) {
base::AutoLock locker(lock_); base::AutoLock locker(lock_);
DCHECK(has_local_consumer_no_lock()); DCHECK(has_local_consumer_no_lock());
...@@ -261,21 +266,27 @@ MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes, ...@@ -261,21 +266,27 @@ MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes,
if (consumer_in_two_phase_read_no_lock()) if (consumer_in_two_phase_read_no_lock())
return MOJO_RESULT_BUSY; return MOJO_RESULT_BUSY;
if (*num_bytes % element_num_bytes_ != 0) 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; return MOJO_RESULT_INVALID_ARGUMENT;
if (*num_bytes == 0) if (max_num_bytes_to_discard == 0)
return MOJO_RESULT_OK; // Nothing to do. 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 = ProducerGetHandleSignalsStateNoLock(); HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock();
MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none); MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes,
max_num_bytes_to_discard,
min_num_bytes_to_discard);
HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock();
if (!new_producer_state.equals(old_producer_state)) if (!new_producer_state.equals(old_producer_state))
AwakeProducerWaitersForStateChangeNoLock(new_producer_state); AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
return rv; return rv;
} }
MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) { MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) {
base::AutoLock locker(lock_); base::AutoLock locker(lock_);
DCHECK(has_local_consumer_no_lock()); DCHECK(has_local_consumer_no_lock());
......
...@@ -71,12 +71,12 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe : ...@@ -71,12 +71,12 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
void ConsumerClose(); void ConsumerClose();
// This does not validate its arguments, except to check that |*num_bytes| is // This does not validate its arguments, except to check that |*num_bytes| is
// a multiple of |element_num_bytes_|. // a multiple of |element_num_bytes_|.
MojoResult ConsumerReadData(void* elements, MojoResult ConsumerReadData(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
bool all_or_none); bool all_or_none);
MojoResult ConsumerDiscardData(uint32_t* num_bytes, MojoResult ConsumerDiscardData(UserPointer<uint32_t> num_bytes,
bool all_or_none); bool all_or_none);
MojoResult ConsumerQueryData(uint32_t* num_bytes); MojoResult ConsumerQueryData(UserPointer<uint32_t> num_bytes);
MojoResult ConsumerBeginReadData(UserPointer<const void*> buffer, MojoResult ConsumerBeginReadData(UserPointer<const void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
bool all_or_none); bool all_or_none);
...@@ -111,13 +111,18 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe : ...@@ -111,13 +111,18 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
virtual void ConsumerCloseImplNoLock() = 0; virtual void ConsumerCloseImplNoLock() = 0;
// |*num_bytes| will be a nonzero multiple of |element_num_bytes_|. // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ConsumerReadDataImplNoLock(void* elements, virtual MojoResult ConsumerReadDataImplNoLock(
uint32_t* num_bytes, UserPointer<void> elements,
bool all_or_none) = 0; UserPointer<uint32_t> num_bytes,
virtual MojoResult ConsumerDiscardDataImplNoLock(uint32_t* num_bytes, uint32_t max_num_bytes_to_read,
bool all_or_none) = 0; uint32_t min_num_bytes_to_read) = 0;
virtual MojoResult ConsumerDiscardDataImplNoLock(
UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_discard,
uint32_t min_num_bytes_to_discard) = 0;
// |*num_bytes| will be a nonzero multiple of |element_num_bytes_|. // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ConsumerQueryDataImplNoLock(uint32_t* num_bytes) = 0; virtual MojoResult ConsumerQueryDataImplNoLock(
UserPointer<uint32_t> num_bytes) = 0;
virtual MojoResult ConsumerBeginReadDataImplNoLock( virtual MojoResult ConsumerBeginReadDataImplNoLock(
UserPointer<const void*> buffer, UserPointer<const void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
......
...@@ -51,33 +51,28 @@ DataPipeConsumerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { ...@@ -51,33 +51,28 @@ DataPipeConsumerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
} }
MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock( MojoResult DataPipeConsumerDispatcher::ReadDataImplNoLock(
void* elements, UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoReadDataFlags flags) { MojoReadDataFlags flags) {
lock().AssertAcquired(); lock().AssertAcquired();
if (!VerifyUserPointer<uint32_t>(num_bytes))
return MOJO_RESULT_INVALID_ARGUMENT;
if ((flags & MOJO_READ_DATA_FLAG_DISCARD)) { if ((flags & MOJO_READ_DATA_FLAG_DISCARD)) {
// These flags are mutally exclusive. // These flags are mutally exclusive.
if ((flags & MOJO_READ_DATA_FLAG_QUERY)) if ((flags & MOJO_READ_DATA_FLAG_QUERY))
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
DVLOG_IF(2, elements) << "Discard mode: ignoring non-null |elements|"; DVLOG_IF(2, !elements.IsNull())
<< "Discard mode: ignoring non-null |elements|";
return data_pipe_->ConsumerDiscardData( return data_pipe_->ConsumerDiscardData(
num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE)); num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE));
} }
if ((flags & MOJO_READ_DATA_FLAG_QUERY)) { if ((flags & MOJO_READ_DATA_FLAG_QUERY)) {
DCHECK(!(flags & MOJO_READ_DATA_FLAG_DISCARD)); // Handled above. DCHECK(!(flags & MOJO_READ_DATA_FLAG_DISCARD)); // Handled above.
DVLOG_IF(2, elements) << "Query mode: ignoring non-null |elements|"; DVLOG_IF(2, !elements.IsNull())
<< "Query mode: ignoring non-null |elements|";
return data_pipe_->ConsumerQueryData(num_bytes); return data_pipe_->ConsumerQueryData(num_bytes);
} }
// Only verify |elements| if we're neither discarding nor querying.
if (!VerifyUserPointerWithSize<1>(elements, *num_bytes))
return MOJO_RESULT_INVALID_ARGUMENT;
return data_pipe_->ConsumerReadData( return data_pipe_->ConsumerReadData(
elements, num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE)); elements, num_bytes, (flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE));
} }
......
...@@ -37,8 +37,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipeConsumerDispatcher : public Dispatcher { ...@@ -37,8 +37,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipeConsumerDispatcher : public Dispatcher {
virtual void CloseImplNoLock() OVERRIDE; virtual void CloseImplNoLock() OVERRIDE;
virtual scoped_refptr<Dispatcher> virtual scoped_refptr<Dispatcher>
CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE; CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE;
virtual MojoResult ReadDataImplNoLock(void* elements, virtual MojoResult ReadDataImplNoLock(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoReadDataFlags flags) OVERRIDE; MojoReadDataFlags flags) OVERRIDE;
virtual MojoResult BeginReadDataImplNoLock( virtual MojoResult BeginReadDataImplNoLock(
UserPointer<const void*> buffer, UserPointer<const void*> buffer,
......
...@@ -164,8 +164,8 @@ MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { ...@@ -164,8 +164,8 @@ MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
return EndWriteDataImplNoLock(num_bytes_written); return EndWriteDataImplNoLock(num_bytes_written);
} }
MojoResult Dispatcher::ReadData(void* elements, MojoResult Dispatcher::ReadData(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoReadDataFlags flags) { MojoReadDataFlags flags) {
base::AutoLock locker(lock_); base::AutoLock locker(lock_);
if (is_closed_) if (is_closed_)
...@@ -303,8 +303,8 @@ MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) { ...@@ -303,8 +303,8 @@ MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
} }
MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/,
uint32_t* /*num_bytes*/, UserPointer<uint32_t> /*num_bytes*/,
MojoReadDataFlags /*flags*/) { MojoReadDataFlags /*flags*/) {
lock_.AssertAcquired(); lock_.AssertAcquired();
DCHECK(!is_closed_); DCHECK(!is_closed_);
......
...@@ -99,8 +99,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -99,8 +99,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
MojoWriteDataFlags flags); MojoWriteDataFlags flags);
MojoResult EndWriteData(uint32_t num_bytes_written); MojoResult EndWriteData(uint32_t num_bytes_written);
MojoResult ReadData(void* elements, MojoResult ReadData(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoReadDataFlags flags); MojoReadDataFlags flags);
MojoResult BeginReadData(UserPointer<const void*> buffer, MojoResult BeginReadData(UserPointer<const void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
...@@ -230,8 +230,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -230,8 +230,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
MojoWriteDataFlags flags); MojoWriteDataFlags flags);
virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written); virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written);
virtual MojoResult ReadDataImplNoLock(void* elements, virtual MojoResult ReadDataImplNoLock(UserPointer<void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoReadDataFlags flags); MojoReadDataFlags flags);
virtual MojoResult BeginReadDataImplNoLock( virtual MojoResult BeginReadDataImplNoLock(
UserPointer<const void*> buffer, UserPointer<const void*> buffer,
......
...@@ -59,7 +59,8 @@ TEST(DispatcherTest, Basic) { ...@@ -59,7 +59,8 @@ TEST(DispatcherTest, Basic) {
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->EndWriteData(0)); d->EndWriteData(0));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->ReadData(NULL, NULL, MOJO_READ_DATA_FLAG_NONE)); d->ReadData(NullUserPointer(), NullUserPointer(),
MOJO_READ_DATA_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->BeginReadData(NullUserPointer(), NullUserPointer(), d->BeginReadData(NullUserPointer(), NullUserPointer(),
MOJO_READ_DATA_FLAG_NONE)); MOJO_READ_DATA_FLAG_NONE));
...@@ -89,7 +90,8 @@ TEST(DispatcherTest, Basic) { ...@@ -89,7 +90,8 @@ TEST(DispatcherTest, Basic) {
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->EndWriteData(0)); d->EndWriteData(0));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->ReadData(NULL, NULL, MOJO_READ_DATA_FLAG_NONE)); d->ReadData(NullUserPointer(), NullUserPointer(),
MOJO_READ_DATA_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->BeginReadData(NullUserPointer(), NullUserPointer(), d->BeginReadData(NullUserPointer(), NullUserPointer(),
MOJO_READ_DATA_FLAG_NONE)); MOJO_READ_DATA_FLAG_NONE));
...@@ -175,7 +177,8 @@ class ThreadSafetyStressThread : public base::SimpleThread { ...@@ -175,7 +177,8 @@ class ThreadSafetyStressThread : public base::SimpleThread {
break; break;
case READ_DATA: case READ_DATA:
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dispatcher_->ReadData(NULL, NULL, MOJO_READ_DATA_FLAG_NONE)); dispatcher_->ReadData(NullUserPointer(), NullUserPointer(),
MOJO_READ_DATA_FLAG_NONE));
break; break;
case BEGIN_READ_DATA: case BEGIN_READ_DATA:
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but // E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but
// their sum may not. This is bad and poses a security risk. (We're currently // their sum may not. This is bad and poses a security risk. (We're currently
// saved by the limit on capacity -- the maximum size of the buffer, checked in // saved by the limit on capacity -- the maximum size of the buffer, checked in
// |DataPipe::ValidateOptions()|, is currently sufficiently small. // |DataPipe::ValidateOptions()|, is currently sufficiently small.)
#include "mojo/system/local_data_pipe.h" #include "mojo/system/local_data_pipe.h"
...@@ -171,13 +171,16 @@ void LocalDataPipe::ConsumerCloseImplNoLock() { ...@@ -171,13 +171,16 @@ void LocalDataPipe::ConsumerCloseImplNoLock() {
current_num_bytes_ = 0; current_num_bytes_ = 0;
} }
MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements, MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(
uint32_t* num_bytes, UserPointer<void> elements,
bool all_or_none) { UserPointer<uint32_t> num_bytes,
DCHECK_EQ(*num_bytes % element_num_bytes(), 0u); uint32_t max_num_bytes_to_read,
DCHECK_GT(*num_bytes, 0u); uint32_t min_num_bytes_to_read) {
DCHECK_EQ(max_num_bytes_to_read % element_num_bytes(), 0u);
DCHECK_EQ(min_num_bytes_to_read % element_num_bytes(), 0u);
DCHECK_GT(max_num_bytes_to_read, 0u);
if (all_or_none && *num_bytes > current_num_bytes_) { if (min_num_bytes_to_read > current_num_bytes_) {
// Don't return "should wait" since you can't wait for a specified amount of // Don't return "should wait" since you can't wait for a specified amount of
// data. // data.
return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE : return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE :
...@@ -185,7 +188,7 @@ MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements, ...@@ -185,7 +188,7 @@ MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements,
} }
size_t num_bytes_to_read = size_t num_bytes_to_read =
std::min(static_cast<size_t>(*num_bytes), current_num_bytes_); std::min(static_cast<size_t>(max_num_bytes_to_read), current_num_bytes_);
if (num_bytes_to_read == 0) { if (num_bytes_to_read == 0) {
return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT : return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT :
MOJO_RESULT_FAILED_PRECONDITION; MOJO_RESULT_FAILED_PRECONDITION;
...@@ -194,26 +197,28 @@ MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements, ...@@ -194,26 +197,28 @@ MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements,
// The amount we can read in our first |memcpy()|. // The amount we can read in our first |memcpy()|.
size_t num_bytes_to_read_first = size_t num_bytes_to_read_first =
std::min(num_bytes_to_read, GetMaxNumBytesToReadNoLock()); std::min(num_bytes_to_read, GetMaxNumBytesToReadNoLock());
memcpy(elements, buffer_.get() + start_index_, num_bytes_to_read_first); elements.PutArray(buffer_.get() + start_index_, num_bytes_to_read_first);
if (num_bytes_to_read_first < num_bytes_to_read) { if (num_bytes_to_read_first < num_bytes_to_read) {
// The "second read index" is zero. // The "second read index" is zero.
memcpy(static_cast<char*>(elements) + num_bytes_to_read_first, elements.At(num_bytes_to_read_first).PutArray(
buffer_.get(), buffer_.get(), num_bytes_to_read - num_bytes_to_read_first);
num_bytes_to_read - num_bytes_to_read_first);
} }
MarkDataAsConsumedNoLock(num_bytes_to_read); MarkDataAsConsumedNoLock(num_bytes_to_read);
*num_bytes = static_cast<uint32_t>(num_bytes_to_read); num_bytes.Put(static_cast<uint32_t>(num_bytes_to_read));
return MOJO_RESULT_OK; return MOJO_RESULT_OK;
} }
MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(uint32_t* num_bytes, MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(
bool all_or_none) { UserPointer<uint32_t> num_bytes,
DCHECK_EQ(*num_bytes % element_num_bytes(), 0u); uint32_t max_num_bytes_to_discard,
DCHECK_GT(*num_bytes, 0u); uint32_t min_num_bytes_to_discard) {
DCHECK_EQ(max_num_bytes_to_discard % element_num_bytes(), 0u);
DCHECK_EQ(min_num_bytes_to_discard % element_num_bytes(), 0u);
DCHECK_GT(max_num_bytes_to_discard, 0u);
if (all_or_none && *num_bytes > current_num_bytes_) { if (min_num_bytes_to_discard > current_num_bytes_) {
// Don't return "should wait" since you can't wait for a specified amount of // Don't return "should wait" since you can't wait for a specified amount of
// data. // data.
return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE : return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE :
...@@ -227,15 +232,17 @@ MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(uint32_t* num_bytes, ...@@ -227,15 +232,17 @@ MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(uint32_t* num_bytes,
} }
size_t num_bytes_to_discard = size_t num_bytes_to_discard =
std::min(static_cast<size_t>(*num_bytes), current_num_bytes_); std::min(static_cast<size_t>(max_num_bytes_to_discard),
current_num_bytes_);
MarkDataAsConsumedNoLock(num_bytes_to_discard); MarkDataAsConsumedNoLock(num_bytes_to_discard);
*num_bytes = static_cast<uint32_t>(num_bytes_to_discard); num_bytes.Put(static_cast<uint32_t>(num_bytes_to_discard));
return MOJO_RESULT_OK; return MOJO_RESULT_OK;
} }
MojoResult LocalDataPipe::ConsumerQueryDataImplNoLock(uint32_t* num_bytes) { MojoResult LocalDataPipe::ConsumerQueryDataImplNoLock(
UserPointer<uint32_t> num_bytes) {
// Note: This cast is safe, since the capacity fits into a |uint32_t|. // Note: This cast is safe, since the capacity fits into a |uint32_t|.
*num_bytes = static_cast<uint32_t>(current_num_bytes_); num_bytes.Put(static_cast<uint32_t>(current_num_bytes_));
return MOJO_RESULT_OK; return MOJO_RESULT_OK;
} }
......
...@@ -43,12 +43,17 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe { ...@@ -43,12 +43,17 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe {
virtual HandleSignalsState virtual HandleSignalsState
ProducerGetHandleSignalsStateNoLock() const OVERRIDE; ProducerGetHandleSignalsStateNoLock() const OVERRIDE;
virtual void ConsumerCloseImplNoLock() OVERRIDE; virtual void ConsumerCloseImplNoLock() OVERRIDE;
virtual MojoResult ConsumerReadDataImplNoLock(void* elements, virtual MojoResult ConsumerReadDataImplNoLock(
uint32_t* num_bytes, UserPointer<void> elements,
bool all_or_none) OVERRIDE; UserPointer<uint32_t> num_bytes,
virtual MojoResult ConsumerDiscardDataImplNoLock(uint32_t* num_bytes, uint32_t max_num_bytes_to_read,
bool all_or_none) OVERRIDE; uint32_t min_num_bytes_to_read) OVERRIDE;
virtual MojoResult ConsumerQueryDataImplNoLock(uint32_t* num_bytes) OVERRIDE; virtual MojoResult ConsumerDiscardDataImplNoLock(
UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_discard,
uint32_t min_num_bytes_to_discard) OVERRIDE;
virtual MojoResult ConsumerQueryDataImplNoLock(
UserPointer<uint32_t> num_bytes) OVERRIDE;
virtual MojoResult ConsumerBeginReadDataImplNoLock( virtual MojoResult ConsumerBeginReadDataImplNoLock(
UserPointer<const void*> buffer, UserPointer<const void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
......
This diff is collapsed.
...@@ -181,11 +181,10 @@ class UserPointer { ...@@ -181,11 +181,10 @@ class UserPointer {
memcpy(pointer_, source, count * sizeof(NonVoidType)); memcpy(pointer_, source, count * sizeof(NonVoidType));
} }
// Gets a |UserPointer| at offset |i| (in |Type|s) relative to this. This // Gets a |UserPointer| at offset |i| (in |Type|s) relative to this.
// method is not valid if |Type| is |void| (TODO(vtl): Maybe I should make it
// valid, with the offset in bytes?).
UserPointer At(size_t i) const { UserPointer At(size_t i) const {
return UserPointer(pointer_ + i); return UserPointer(static_cast<Type*>(
static_cast<NonVoidType*>(pointer_) + i));
} }
// TODO(vtl): This is temporary. Get rid of this. (We should pass // TODO(vtl): This is temporary. Get rid of this. (We should pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment