| Index: content/child/resource_dispatcher.cc
|
| diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
|
| index cf56a77c8a0556d01b64afb1d40e1bbba3732faa..485d2e35b1e172e191ac6eeda609b47c14c8d56b 100644
|
| --- a/content/child/resource_dispatcher.cc
|
| +++ b/content/child/resource_dispatcher.cc
|
| @@ -16,6 +16,7 @@
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/string_util.h"
|
| +#include "content/child/ref_counted_shared_memory.h"
|
| #include "content/child/request_extra_data.h"
|
| #include "content/child/request_info.h"
|
| #include "content/child/site_isolation_policy.h"
|
| @@ -36,6 +37,44 @@ namespace content {
|
|
|
| namespace {
|
|
|
| +class SharedMemoryReceivedData final : public RequestPeer::ReceivedData {
|
| + public:
|
| + SharedMemoryReceivedData(const char* payload,
|
| + int length,
|
| + int encoded_length,
|
| + IPC::Sender* message_sender,
|
| + int request_id,
|
| + scoped_refptr<RefCountedSharedMemory> shm_buffer)
|
| + : payload_(payload),
|
| + length_(length),
|
| + encoded_length_(encoded_length),
|
| + message_sender_(message_sender),
|
| + request_id_(request_id),
|
| + shm_buffer_(shm_buffer) {}
|
| + ~SharedMemoryReceivedData() override {
|
| + message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_));
|
| + }
|
| +
|
| + const char* payload() const override { return payload_; }
|
| + int length() const override { return length_; }
|
| + int encoded_length() const override { return encoded_length_; }
|
| +
|
| + private:
|
| + const char* const payload_;
|
| + const int length_;
|
| + const int encoded_length_;
|
| +
|
| + // We assume that |message_sender_| outlives this object. This is true because
|
| + // the sender is provided from |ResourceDispatcher::sender_| and it's a
|
| + // ChildThreadImpl.
|
| + IPC::Sender* const message_sender_;
|
| + const int request_id_;
|
| + // Just to keep |payload_| alive while this object is alive.
|
| + scoped_refptr<RefCountedSharedMemory> shm_buffer_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SharedMemoryReceivedData);
|
| +};
|
| +
|
| // Converts |time| from a remote to local TimeTicks, overwriting the original
|
| // value.
|
| void RemoteToLocalTimeTicks(
|
| @@ -189,10 +228,10 @@ void ResourceDispatcher::OnSetDataBuffer(int request_id,
|
| bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle);
|
| CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size));
|
|
|
| - request_info->buffer.reset(
|
| - new base::SharedMemory(shm_handle, true)); // read only
|
| + request_info->buffer = make_scoped_refptr(
|
| + new RefCountedSharedMemory(shm_handle, true)); // read only
|
|
|
| - bool ok = request_info->buffer->Map(shm_size);
|
| + bool ok = request_info->buffer->memory().Map(shm_size);
|
| if (!ok) {
|
| // Added to help debug crbug/160401.
|
| base::ProcessId renderer_pid_copy = renderer_pid;
|
| @@ -217,16 +256,18 @@ void ResourceDispatcher::OnReceivedData(int request_id,
|
| PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
|
| bool send_ack = true;
|
| if (request_info && data_length > 0) {
|
| - CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle()));
|
| + CHECK(base::SharedMemory::IsHandleValid(
|
| + request_info->buffer->memory().handle()));
|
| CHECK_GE(request_info->buffer_size, data_offset + data_length);
|
|
|
| // Ensure that the SHM buffer remains valid for the duration of this scope.
|
| // It is possible for Cancel() to be called before we exit this scope.
|
| - linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer);
|
| + scoped_refptr<RefCountedSharedMemory> retain_buffer(request_info->buffer);
|
|
|
| base::TimeTicks time_start = base::TimeTicks::Now();
|
|
|
| - const char* data_start = static_cast<char*>(request_info->buffer->memory());
|
| + const char* data_start =
|
| + static_cast<char*>(request_info->buffer->memory().memory());
|
| CHECK(data_start);
|
| CHECK(data_start + data_offset);
|
| const char* data_ptr = data_start + data_offset;
|
| @@ -259,8 +300,14 @@ void ResourceDispatcher::OnReceivedData(int request_id,
|
| // data may be processed later on another thread.
|
| send_ack = false;
|
| } else {
|
| + // The SharedMemoryReceivedData sends the ack signal on destruction.
|
| + send_ack = false;
|
| + // It's OK to pass the buffer because we don't use |data_ptr| in this
|
| + // function from now.
|
| request_info->peer->OnReceivedData(
|
| - data_ptr, data_length, encoded_data_length);
|
| + make_scoped_ptr(new SharedMemoryReceivedData(
|
| + data_ptr, data_length, encoded_data_length, message_sender_,
|
| + request_id, retain_buffer.Pass())));
|
| }
|
| }
|
|
|
| @@ -335,7 +382,7 @@ void ResourceDispatcher::OnRequestComplete(
|
| if (!request_info)
|
| return;
|
| request_info->completion_time = ConsumeIOTimestamp();
|
| - request_info->buffer.reset();
|
| + request_info->buffer = nullptr;
|
| request_info->buffer_size = 0;
|
|
|
| RequestPeer* peer = request_info->peer;
|
|
|