Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1350)

Unified Diff: content/child/resource_dispatcher.cc

Issue 1103813002: Make WebURLLoader capable of retaining received buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698