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

R=darin@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285782 0039d316-1c4b-4281-b951-d872f2087c98
parent b1480c5d
...@@ -360,8 +360,7 @@ MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, ...@@ -360,8 +360,7 @@ MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle,
if (!dispatcher) if (!dispatcher)
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
return dispatcher->WriteData(elements.GetPointerUnsafe(), return dispatcher->WriteData(elements, num_bytes, flags);
num_bytes.GetPointerUnsafe(), flags);
} }
MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle,
......
...@@ -84,8 +84,8 @@ class MockDispatcher : public Dispatcher { ...@@ -84,8 +84,8 @@ class MockDispatcher : public Dispatcher {
} }
virtual MojoResult WriteDataImplNoLock( virtual MojoResult WriteDataImplNoLock(
const void* /*elements*/, UserPointer<const void> /*elements*/,
uint32_t* /*num_bytes*/, UserPointer<uint32_t> /*num_bytes*/,
MojoWriteDataFlags /*flags*/) OVERRIDE { MojoWriteDataFlags /*flags*/) OVERRIDE {
info_->IncrementWriteDataCallCount(); info_->IncrementWriteDataCallCount();
lock().AssertAcquired(); lock().AssertAcquired();
......
...@@ -94,8 +94,8 @@ void DataPipe::ProducerClose() { ...@@ -94,8 +94,8 @@ void DataPipe::ProducerClose() {
ConsumerGetHandleSignalsStateNoLock()); ConsumerGetHandleSignalsStateNoLock());
} }
MojoResult DataPipe::ProducerWriteData(const void* elements, MojoResult DataPipe::ProducerWriteData(UserPointer<const 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_producer_no_lock()); DCHECK(has_local_producer_no_lock());
...@@ -106,14 +106,19 @@ MojoResult DataPipe::ProducerWriteData(const void* elements, ...@@ -106,14 +106,19 @@ MojoResult DataPipe::ProducerWriteData(const void* elements,
return MOJO_RESULT_FAILED_PRECONDITION; return MOJO_RESULT_FAILED_PRECONDITION;
// Returning "busy" takes priority over "invalid argument". // Returning "busy" takes priority over "invalid argument".
if (*num_bytes % element_num_bytes_ != 0) 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; return MOJO_RESULT_INVALID_ARGUMENT;
if (*num_bytes == 0) if (max_num_bytes_to_write == 0)
return MOJO_RESULT_OK; // Nothing to do. 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 = ConsumerGetHandleSignalsStateNoLock(); HandleSignalsState old_consumer_state = ConsumerGetHandleSignalsStateNoLock();
MojoResult rv = ProducerWriteDataImplNoLock(elements, num_bytes, all_or_none); MojoResult rv = ProducerWriteDataImplNoLock(elements, num_bytes,
max_num_bytes_to_write,
min_num_bytes_to_write);
HandleSignalsState new_consumer_state = ConsumerGetHandleSignalsStateNoLock(); HandleSignalsState new_consumer_state = ConsumerGetHandleSignalsStateNoLock();
if (!new_consumer_state.equals(old_consumer_state)) if (!new_consumer_state.equals(old_consumer_state))
AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state); AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state);
......
...@@ -50,10 +50,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe : ...@@ -50,10 +50,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
// corresponding names. // corresponding names.
void ProducerCancelAllWaiters(); void ProducerCancelAllWaiters();
void ProducerClose(); void ProducerClose();
// This does not validate its arguments, except to check that |*num_bytes| is MojoResult ProducerWriteData(UserPointer<const void> elements,
// a multiple of |element_num_bytes_|. UserPointer<uint32_t> num_bytes,
MojoResult ProducerWriteData(const void* elements,
uint32_t* num_bytes,
bool all_or_none); bool all_or_none);
MojoResult ProducerBeginWriteData(UserPointer<void*> buffer, MojoResult ProducerBeginWriteData(UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
...@@ -96,10 +94,12 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe : ...@@ -96,10 +94,12 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
virtual ~DataPipe(); virtual ~DataPipe();
virtual void ProducerCloseImplNoLock() = 0; virtual void ProducerCloseImplNoLock() = 0;
// |*num_bytes| will be a nonzero multiple of |element_num_bytes_|. // |num_bytes.Get()| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ProducerWriteDataImplNoLock(const void* elements, virtual MojoResult ProducerWriteDataImplNoLock(
uint32_t* num_bytes, UserPointer<const void> elements,
bool all_or_none) = 0; UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_write,
uint32_t min_num_bytes_to_write) = 0;
virtual MojoResult ProducerBeginWriteDataImplNoLock( virtual MojoResult ProducerBeginWriteDataImplNoLock(
UserPointer<void*> buffer, UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
......
...@@ -51,16 +51,10 @@ DataPipeProducerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { ...@@ -51,16 +51,10 @@ DataPipeProducerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
} }
MojoResult DataPipeProducerDispatcher::WriteDataImplNoLock( MojoResult DataPipeProducerDispatcher::WriteDataImplNoLock(
const void* elements, UserPointer<const void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) { MojoWriteDataFlags flags) {
lock().AssertAcquired(); lock().AssertAcquired();
if (!VerifyUserPointer<uint32_t>(num_bytes))
return MOJO_RESULT_INVALID_ARGUMENT;
if (!VerifyUserPointerWithSize<1>(elements, *num_bytes))
return MOJO_RESULT_INVALID_ARGUMENT;
return data_pipe_->ProducerWriteData( return data_pipe_->ProducerWriteData(
elements, num_bytes, (flags & MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); elements, num_bytes, (flags & MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
} }
......
...@@ -37,8 +37,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipeProducerDispatcher : public Dispatcher { ...@@ -37,8 +37,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipeProducerDispatcher : public Dispatcher {
virtual void CloseImplNoLock() OVERRIDE; virtual void CloseImplNoLock() OVERRIDE;
virtual scoped_refptr<Dispatcher> virtual scoped_refptr<Dispatcher>
CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE; CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE;
virtual MojoResult WriteDataImplNoLock(const void* elements, virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) OVERRIDE; MojoWriteDataFlags flags) OVERRIDE;
virtual MojoResult BeginWriteDataImplNoLock( virtual MojoResult BeginWriteDataImplNoLock(
UserPointer<void*> buffer, UserPointer<void*> buffer,
......
...@@ -136,8 +136,8 @@ MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes, ...@@ -136,8 +136,8 @@ MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
flags); flags);
} }
MojoResult Dispatcher::WriteData(const void* elements, MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) { MojoWriteDataFlags flags) {
base::AutoLock locker(lock_); base::AutoLock locker(lock_);
if (is_closed_) if (is_closed_)
...@@ -277,8 +277,8 @@ MojoResult Dispatcher::ReadMessageImplNoLock( ...@@ -277,8 +277,8 @@ MojoResult Dispatcher::ReadMessageImplNoLock(
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
} }
MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
uint32_t* /*num_bytes*/, UserPointer<uint32_t> /*num_bytes*/,
MojoWriteDataFlags /*flags*/) { MojoWriteDataFlags /*flags*/) {
lock_.AssertAcquired(); lock_.AssertAcquired();
DCHECK(!is_closed_); DCHECK(!is_closed_);
......
...@@ -92,8 +92,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -92,8 +92,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
DispatcherVector* dispatchers, DispatcherVector* dispatchers,
uint32_t* num_dispatchers, uint32_t* num_dispatchers,
MojoReadMessageFlags flags); MojoReadMessageFlags flags);
MojoResult WriteData(const void* elements, MojoResult WriteData(UserPointer<const void> elements,
uint32_t* elements_num_bytes, UserPointer<uint32_t> elements_num_bytes,
MojoWriteDataFlags flags); MojoWriteDataFlags flags);
MojoResult BeginWriteData(UserPointer<void*> buffer, MojoResult BeginWriteData(UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
...@@ -222,8 +222,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -222,8 +222,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
DispatcherVector* dispatchers, DispatcherVector* dispatchers,
uint32_t* num_dispatchers, uint32_t* num_dispatchers,
MojoReadMessageFlags flags); MojoReadMessageFlags flags);
virtual MojoResult WriteDataImplNoLock(const void* elements, virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
uint32_t* num_bytes, UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags); MojoWriteDataFlags flags);
virtual MojoResult BeginWriteDataImplNoLock( virtual MojoResult BeginWriteDataImplNoLock(
UserPointer<void*> buffer, UserPointer<void*> buffer,
......
...@@ -52,7 +52,8 @@ TEST(DispatcherTest, Basic) { ...@@ -52,7 +52,8 @@ TEST(DispatcherTest, Basic) {
d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL, d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL,
MOJO_WRITE_MESSAGE_FLAG_NONE)); MOJO_WRITE_MESSAGE_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->WriteData(NULL, NULL, MOJO_WRITE_DATA_FLAG_NONE)); d->WriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->BeginWriteData(NullUserPointer(), NullUserPointer(), d->BeginWriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE)); MOJO_WRITE_DATA_FLAG_NONE));
...@@ -83,7 +84,8 @@ TEST(DispatcherTest, Basic) { ...@@ -83,7 +84,8 @@ TEST(DispatcherTest, Basic) {
d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL, d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL,
MOJO_WRITE_MESSAGE_FLAG_NONE)); MOJO_WRITE_MESSAGE_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->WriteData(NULL, NULL, MOJO_WRITE_DATA_FLAG_NONE)); d->WriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
d->BeginWriteData(NullUserPointer(), NullUserPointer(), d->BeginWriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE)); MOJO_WRITE_DATA_FLAG_NONE));
...@@ -162,7 +164,7 @@ class ThreadSafetyStressThread : public base::SimpleThread { ...@@ -162,7 +164,7 @@ class ThreadSafetyStressThread : public base::SimpleThread {
break; break;
case WRITE_DATA: case WRITE_DATA:
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dispatcher_->WriteData(NULL, NULL, dispatcher_->WriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE)); MOJO_WRITE_DATA_FLAG_NONE));
break; break;
case BEGIN_WRITE_DATA: case BEGIN_WRITE_DATA:
......
...@@ -44,19 +44,22 @@ void LocalDataPipe::ProducerCloseImplNoLock() { ...@@ -44,19 +44,22 @@ void LocalDataPipe::ProducerCloseImplNoLock() {
} }
} }
MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements, MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(
uint32_t* num_bytes, UserPointer<const 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_write,
DCHECK_GT(*num_bytes, 0u); uint32_t min_num_bytes_to_write) {
DCHECK_EQ(max_num_bytes_to_write % element_num_bytes(), 0u);
DCHECK_EQ(min_num_bytes_to_write % element_num_bytes(), 0u);
DCHECK_GT(max_num_bytes_to_write, 0u);
DCHECK(consumer_open_no_lock()); DCHECK(consumer_open_no_lock());
size_t num_bytes_to_write = 0; size_t num_bytes_to_write = 0;
if (may_discard()) { if (may_discard()) {
if (all_or_none && *num_bytes > capacity_num_bytes()) if (min_num_bytes_to_write > capacity_num_bytes())
return MOJO_RESULT_OUT_OF_RANGE; return MOJO_RESULT_OUT_OF_RANGE;
num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes), num_bytes_to_write = std::min(static_cast<size_t>(max_num_bytes_to_write),
capacity_num_bytes()); capacity_num_bytes());
if (num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) { if (num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) {
// Discard as much as needed (discard oldest first). // Discard as much as needed (discard oldest first).
...@@ -66,13 +69,13 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements, ...@@ -66,13 +69,13 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
// the buffer full. // the buffer full.
} }
} else { } else {
if (all_or_none && *num_bytes > capacity_num_bytes() - current_num_bytes_) { if (min_num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) {
// Don't return "should wait" since you can't wait for a specified amount // Don't return "should wait" since you can't wait for a specified amount
// of data. // of data.
return MOJO_RESULT_OUT_OF_RANGE; return MOJO_RESULT_OUT_OF_RANGE;
} }
num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes), num_bytes_to_write = std::min(static_cast<size_t>(max_num_bytes_to_write),
capacity_num_bytes() - current_num_bytes_); capacity_num_bytes() - current_num_bytes_);
} }
if (num_bytes_to_write == 0) if (num_bytes_to_write == 0)
...@@ -85,18 +88,18 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements, ...@@ -85,18 +88,18 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
size_t first_write_index = size_t first_write_index =
(start_index_ + current_num_bytes_) % capacity_num_bytes(); (start_index_ + current_num_bytes_) % capacity_num_bytes();
EnsureBufferNoLock(); EnsureBufferNoLock();
memcpy(buffer_.get() + first_write_index, elements, num_bytes_to_write_first); elements.GetArray(buffer_.get() + first_write_index,
num_bytes_to_write_first);
if (num_bytes_to_write_first < num_bytes_to_write) { if (num_bytes_to_write_first < num_bytes_to_write) {
// The "second write index" is zero. // The "second write index" is zero.
memcpy(buffer_.get(), elements.At(num_bytes_to_write_first).GetArray(
static_cast<const char*>(elements) + num_bytes_to_write_first, buffer_.get(), num_bytes_to_write - num_bytes_to_write_first);
num_bytes_to_write - num_bytes_to_write_first);
} }
current_num_bytes_ += num_bytes_to_write; current_num_bytes_ += num_bytes_to_write;
DCHECK_LE(current_num_bytes_, capacity_num_bytes()); DCHECK_LE(current_num_bytes_, capacity_num_bytes());
*num_bytes = static_cast<uint32_t>(num_bytes_to_write); num_bytes.Put(static_cast<uint32_t>(num_bytes_to_write));
return MOJO_RESULT_OK; return MOJO_RESULT_OK;
} }
......
...@@ -31,9 +31,11 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe { ...@@ -31,9 +31,11 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe {
// |DataPipe| implementation: // |DataPipe| implementation:
virtual void ProducerCloseImplNoLock() OVERRIDE; virtual void ProducerCloseImplNoLock() OVERRIDE;
virtual MojoResult ProducerWriteDataImplNoLock(const void* elements, virtual MojoResult ProducerWriteDataImplNoLock(
uint32_t* num_bytes, UserPointer<const void> elements,
bool all_or_none) OVERRIDE; UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_write,
uint32_t min_num_bytes_to_write) OVERRIDE;
virtual MojoResult ProducerBeginWriteDataImplNoLock( virtual MojoResult ProducerBeginWriteDataImplNoLock(
UserPointer<void*> buffer, UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes, UserPointer<uint32_t> buffer_num_bytes,
......
This diff is collapsed.
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