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,
if (!dispatcher)
return MOJO_RESULT_INVALID_ARGUMENT;
return dispatcher->WriteData(elements.GetPointerUnsafe(),
num_bytes.GetPointerUnsafe(), flags);
return dispatcher->WriteData(elements, num_bytes, flags);
}
MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle,
......
......@@ -84,8 +84,8 @@ class MockDispatcher : public Dispatcher {
}
virtual MojoResult WriteDataImplNoLock(
const void* /*elements*/,
uint32_t* /*num_bytes*/,
UserPointer<const void> /*elements*/,
UserPointer<uint32_t> /*num_bytes*/,
MojoWriteDataFlags /*flags*/) OVERRIDE {
info_->IncrementWriteDataCallCount();
lock().AssertAcquired();
......
......@@ -94,8 +94,8 @@ void DataPipe::ProducerClose() {
ConsumerGetHandleSignalsStateNoLock());
}
MojoResult DataPipe::ProducerWriteData(const void* elements,
uint32_t* num_bytes,
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());
......@@ -106,14 +106,19 @@ MojoResult DataPipe::ProducerWriteData(const void* elements,
return MOJO_RESULT_FAILED_PRECONDITION;
// 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;
if (*num_bytes == 0)
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 = 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();
if (!new_consumer_state.equals(old_consumer_state))
AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state);
......
......@@ -50,10 +50,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
// corresponding names.
void ProducerCancelAllWaiters();
void ProducerClose();
// This does not validate its arguments, except to check that |*num_bytes| is
// a multiple of |element_num_bytes_|.
MojoResult ProducerWriteData(const void* elements,
uint32_t* num_bytes,
MojoResult ProducerWriteData(UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
bool all_or_none);
MojoResult ProducerBeginWriteData(UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes,
......@@ -96,10 +94,12 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe :
virtual ~DataPipe();
virtual void ProducerCloseImplNoLock() = 0;
// |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ProducerWriteDataImplNoLock(const void* elements,
uint32_t* num_bytes,
bool all_or_none) = 0;
// |num_bytes.Get()| will be a nonzero multiple of |element_num_bytes_|.
virtual MojoResult ProducerWriteDataImplNoLock(
UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_write,
uint32_t min_num_bytes_to_write) = 0;
virtual MojoResult ProducerBeginWriteDataImplNoLock(
UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes,
......
......@@ -51,16 +51,10 @@ DataPipeProducerDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
}
MojoResult DataPipeProducerDispatcher::WriteDataImplNoLock(
const void* elements,
uint32_t* num_bytes,
UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) {
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(
elements, num_bytes, (flags & MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
}
......
......@@ -37,8 +37,8 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipeProducerDispatcher : public Dispatcher {
virtual void CloseImplNoLock() OVERRIDE;
virtual scoped_refptr<Dispatcher>
CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE;
virtual MojoResult WriteDataImplNoLock(const void* elements,
uint32_t* num_bytes,
virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) OVERRIDE;
virtual MojoResult BeginWriteDataImplNoLock(
UserPointer<void*> buffer,
......
......@@ -136,8 +136,8 @@ MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
flags);
}
MojoResult Dispatcher::WriteData(const void* elements,
uint32_t* num_bytes,
MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags) {
base::AutoLock locker(lock_);
if (is_closed_)
......@@ -277,8 +277,8 @@ MojoResult Dispatcher::ReadMessageImplNoLock(
return MOJO_RESULT_INVALID_ARGUMENT;
}
MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/,
uint32_t* /*num_bytes*/,
MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
UserPointer<uint32_t> /*num_bytes*/,
MojoWriteDataFlags /*flags*/) {
lock_.AssertAcquired();
DCHECK(!is_closed_);
......
......@@ -92,8 +92,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
DispatcherVector* dispatchers,
uint32_t* num_dispatchers,
MojoReadMessageFlags flags);
MojoResult WriteData(const void* elements,
uint32_t* elements_num_bytes,
MojoResult WriteData(UserPointer<const void> elements,
UserPointer<uint32_t> elements_num_bytes,
MojoWriteDataFlags flags);
MojoResult BeginWriteData(UserPointer<void*> buffer,
UserPointer<uint32_t> buffer_num_bytes,
......@@ -222,8 +222,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
DispatcherVector* dispatchers,
uint32_t* num_dispatchers,
MojoReadMessageFlags flags);
virtual MojoResult WriteDataImplNoLock(const void* elements,
uint32_t* num_bytes,
virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
MojoWriteDataFlags flags);
virtual MojoResult BeginWriteDataImplNoLock(
UserPointer<void*> buffer,
......
......@@ -52,7 +52,8 @@ TEST(DispatcherTest, Basic) {
d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL,
MOJO_WRITE_MESSAGE_FLAG_NONE));
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,
d->BeginWriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE));
......@@ -83,7 +84,8 @@ TEST(DispatcherTest, Basic) {
d->ReadMessage(NullUserPointer(), NullUserPointer(), NULL, NULL,
MOJO_WRITE_MESSAGE_FLAG_NONE));
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,
d->BeginWriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE));
......@@ -162,7 +164,7 @@ class ThreadSafetyStressThread : public base::SimpleThread {
break;
case WRITE_DATA:
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dispatcher_->WriteData(NULL, NULL,
dispatcher_->WriteData(NullUserPointer(), NullUserPointer(),
MOJO_WRITE_DATA_FLAG_NONE));
break;
case BEGIN_WRITE_DATA:
......
......@@ -44,19 +44,22 @@ void LocalDataPipe::ProducerCloseImplNoLock() {
}
}
MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
uint32_t* num_bytes,
bool all_or_none) {
DCHECK_EQ(*num_bytes % element_num_bytes(), 0u);
DCHECK_GT(*num_bytes, 0u);
MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(
UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_write,
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());
size_t num_bytes_to_write = 0;
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;
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());
if (num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) {
// Discard as much as needed (discard oldest first).
......@@ -66,13 +69,13 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
// the buffer full.
}
} 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
// of data.
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_);
}
if (num_bytes_to_write == 0)
......@@ -85,18 +88,18 @@ MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
size_t first_write_index =
(start_index_ + current_num_bytes_) % capacity_num_bytes();
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) {
// The "second write index" is zero.
memcpy(buffer_.get(),
static_cast<const char*>(elements) + num_bytes_to_write_first,
num_bytes_to_write - num_bytes_to_write_first);
elements.At(num_bytes_to_write_first).GetArray(
buffer_.get(), num_bytes_to_write - num_bytes_to_write_first);
}
current_num_bytes_ += num_bytes_to_write;
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;
}
......
......@@ -31,9 +31,11 @@ class MOJO_SYSTEM_IMPL_EXPORT LocalDataPipe : public DataPipe {
// |DataPipe| implementation:
virtual void ProducerCloseImplNoLock() OVERRIDE;
virtual MojoResult ProducerWriteDataImplNoLock(const void* elements,
uint32_t* num_bytes,
bool all_or_none) OVERRIDE;
virtual MojoResult ProducerWriteDataImplNoLock(
UserPointer<const void> elements,
UserPointer<uint32_t> num_bytes,
uint32_t max_num_bytes_to_write,
uint32_t min_num_bytes_to_write) OVERRIDE;
virtual MojoResult ProducerBeginWriteDataImplNoLock(
UserPointer<void*> buffer,
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