0

Migrate URLLoaderWrapper to base::OnceCallback

Switches chrome_pdf::URLLoaderWrapper's API from pp::CompletionCallback
to base::OnceCallback. pp::CompletionCallback is still used internally
when calling Pepper APIs., but clients of URLLoaderWrapper no longer
need to deal with pp::CompletionCallback.

Using base::OnceCallback also simplifies resource management,
eliminating the need to manage references to pp::CompletionCallback.

With respect to thread safety, most Pepper APIs invoke asynchronous
callbacks on the original caller's thread, so there should be no new
thread safety issues. The base:: APIs also do sequence checking in
DCHECK mode, which should catch any unanticipated issues.

Bug: 1099022, 1101169
Change-Id: Ia355588b25b54a776ac972a7b5b2104b1a3b18c8
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2278169
Commit-Queue: K. Moon <kmoon@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#785816}
This commit is contained in:
K. Moon
2020-07-07 17:08:55 +00:00
committed by Commit Bot
parent 75b18e0451
commit 544e095375
6 changed files with 74 additions and 72 deletions

@ -10,6 +10,8 @@
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h" #include "base/check_op.h"
#include "base/notreached.h" #include "base/notreached.h"
#include "base/numerics/safe_math.h" #include "base/numerics/safe_math.h"
@ -63,8 +65,7 @@ void DocumentLoaderImpl::Chunk::Clear() {
chunk_data.reset(); chunk_data.reset();
} }
DocumentLoaderImpl::DocumentLoaderImpl(Client* client) DocumentLoaderImpl::DocumentLoaderImpl(Client* client) : client_(client) {}
: client_(client), loader_factory_(this) {}
DocumentLoaderImpl::~DocumentLoaderImpl() = default; DocumentLoaderImpl::~DocumentLoaderImpl() = default;
@ -257,9 +258,9 @@ void DocumentLoaderImpl::ContinueDownload() {
loader_ = client_->CreateURLLoader(); loader_ = client_->CreateURLLoader();
loader_->OpenRange( loader_->OpenRange(url_, url_, start, length,
url_, url_, start, length, base::BindOnce(&DocumentLoaderImpl::DidOpenPartial,
loader_factory_.NewCallback(&DocumentLoaderImpl::DidOpenPartial)); weak_factory_.GetWeakPtr()));
} }
void DocumentLoaderImpl::DidOpenPartial(int32_t result) { void DocumentLoaderImpl::DidOpenPartial(int32_t result) {
@ -298,7 +299,7 @@ void DocumentLoaderImpl::DidOpenPartial(int32_t result) {
void DocumentLoaderImpl::ReadMore() { void DocumentLoaderImpl::ReadMore() {
loader_->ReadResponseBody( loader_->ReadResponseBody(
buffer_, sizeof(buffer_), buffer_, sizeof(buffer_),
loader_factory_.NewCallback(&DocumentLoaderImpl::DidRead)); base::BindOnce(&DocumentLoaderImpl::DidRead, weak_factory_.GetWeakPtr()));
} }
void DocumentLoaderImpl::DidRead(int32_t result) { void DocumentLoaderImpl::DidRead(int32_t result) {

@ -5,13 +5,14 @@
#ifndef PDF_DOCUMENT_LOADER_IMPL_H_ #ifndef PDF_DOCUMENT_LOADER_IMPL_H_
#define PDF_DOCUMENT_LOADER_IMPL_H_ #define PDF_DOCUMENT_LOADER_IMPL_H_
#include <stdint.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include "base/macros.h" #include "base/memory/weak_ptr.h"
#include "pdf/chunk_stream.h" #include "pdf/chunk_stream.h"
#include "pdf/document_loader.h" #include "pdf/document_loader.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace chrome_pdf { namespace chrome_pdf {
@ -21,6 +22,8 @@ class DocumentLoaderImpl : public DocumentLoader {
static constexpr uint32_t kDefaultRequestSize = 65536; static constexpr uint32_t kDefaultRequestSize = 65536;
explicit DocumentLoaderImpl(Client* client); explicit DocumentLoaderImpl(Client* client);
DocumentLoaderImpl(const DocumentLoaderImpl&) = delete;
DocumentLoaderImpl& operator=(const DocumentLoaderImpl&) = delete;
~DocumentLoaderImpl() override; ~DocumentLoaderImpl() override;
// DocumentLoader: // DocumentLoader:
@ -75,8 +78,6 @@ class DocumentLoaderImpl : public DocumentLoader {
std::string url_; std::string url_;
std::unique_ptr<URLLoaderWrapper> loader_; std::unique_ptr<URLLoaderWrapper> loader_;
pp::CompletionCallbackFactory<DocumentLoaderImpl> loader_factory_;
DataStream chunk_stream_; DataStream chunk_stream_;
bool partial_loading_enabled_ = true; bool partial_loading_enabled_ = true;
bool is_partial_loader_active_ = false; bool is_partial_loader_active_ = false;
@ -92,7 +93,7 @@ class DocumentLoaderImpl : public DocumentLoader {
uint32_t bytes_received_ = 0; uint32_t bytes_received_ = 0;
DISALLOW_COPY_AND_ASSIGN(DocumentLoaderImpl); base::WeakPtrFactory<DocumentLoaderImpl> weak_factory_{this};
}; };
} // namespace chrome_pdf } // namespace chrome_pdf

@ -7,9 +7,12 @@
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/callback.h"
#include "base/check.h" #include "base/check.h"
#include "pdf/ppapi_migration/callback.h"
#include "pdf/url_loader_wrapper.h" #include "pdf/url_loader_wrapper.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
@ -86,38 +89,38 @@ class TestURLLoader : public URLLoaderWrapper {
open_byte_range_ = open_byte_range; open_byte_range_ = open_byte_range;
} }
bool IsWaitRead() const { return !did_read_callback_.IsOptional(); } bool IsWaitRead() const { return !did_read_callback_.is_null(); }
bool IsWaitOpen() const { return !did_open_callback_.IsOptional(); } bool IsWaitOpen() const { return !did_open_callback_.is_null(); }
char* buffer() const { return buffer_; } char* buffer() const { return buffer_; }
int buffer_size() const { return buffer_size_; } int buffer_size() const { return buffer_size_; }
void SetReadCallback(const pp::CompletionCallback& read_callback, void SetReadCallback(ResultCallback read_callback,
char* buffer, char* buffer,
int buffer_size) { int buffer_size) {
did_read_callback_ = read_callback; did_read_callback_ = std::move(read_callback);
buffer_ = buffer; buffer_ = buffer;
buffer_size_ = buffer_size; buffer_size_ = buffer_size;
} }
void SetOpenCallback(const pp::CompletionCallback& open_callback, void SetOpenCallback(ResultCallback open_callback,
gfx::Range req_byte_range) { gfx::Range req_byte_range) {
did_open_callback_ = open_callback; did_open_callback_ = std::move(open_callback);
set_open_byte_range(req_byte_range); set_open_byte_range(req_byte_range);
} }
void CallOpenCallback(int result) { void CallOpenCallback(int result) {
DCHECK(IsWaitOpen()); DCHECK(IsWaitOpen());
did_open_callback_.RunAndClear(result); std::move(did_open_callback_).Run(result);
} }
void CallReadCallback(int result) { void CallReadCallback(int result) {
DCHECK(IsWaitRead()); DCHECK(IsWaitRead());
did_read_callback_.RunAndClear(result); std::move(did_read_callback_).Run(result);
} }
private: private:
pp::CompletionCallback did_open_callback_; ResultCallback did_open_callback_;
pp::CompletionCallback did_read_callback_; ResultCallback did_read_callback_;
char* buffer_ = nullptr; char* buffer_ = nullptr;
int buffer_size_ = 0; int buffer_size_ = 0;
@ -171,14 +174,15 @@ class TestURLLoader : public URLLoaderWrapper {
const std::string& referrer_url, const std::string& referrer_url,
uint32_t position, uint32_t position,
uint32_t size, uint32_t size,
const pp::CompletionCallback& cc) override { ResultCallback callback) override {
data_->SetOpenCallback(cc, gfx::Range(position, position + size)); data_->SetOpenCallback(std::move(callback),
gfx::Range(position, position + size));
} }
void ReadResponseBody(char* buffer, void ReadResponseBody(char* buffer,
int buffer_size, int buffer_size,
const pp::CompletionCallback& cc) override { ResultCallback callback) override {
data_->SetReadCallback(cc, buffer, buffer_size); data_->SetReadCallback(std::move(callback), buffer, buffer_size);
} }
bool GetDownloadProgress(int64_t* bytes_received, bool GetDownloadProgress(int64_t* bytes_received,

@ -5,10 +5,11 @@
#ifndef PDF_URL_LOADER_WRAPPER_H_ #ifndef PDF_URL_LOADER_WRAPPER_H_
#define PDF_URL_LOADER_WRAPPER_H_ #define PDF_URL_LOADER_WRAPPER_H_
#include <stdint.h>
#include <string> #include <string>
#include "base/macros.h" #include "pdf/ppapi_migration/callback.h"
#include "ppapi/cpp/completion_callback.h"
namespace chrome_pdf { namespace chrome_pdf {
@ -49,14 +50,15 @@ class URLLoaderWrapper {
const std::string& referrer_url, const std::string& referrer_url,
uint32_t position, uint32_t position,
uint32_t size, uint32_t size,
const pp::CompletionCallback& cc) = 0; ResultCallback callback) = 0;
// Read the response body. The size of the buffer must be large enough to // Read the response body. The size of the buffer must be large enough to
// hold the specified number of bytes to read. // hold the specified number of bytes to read.
// This function might perform a partial read. // This function might perform a partial read.
virtual void ReadResponseBody(char* buffer, virtual void ReadResponseBody(char* buffer,
int buffer_size, int buffer_size,
const pp::CompletionCallback& cc) = 0; ResultCallback callback) = 0;
// Returns the current download progress. // Returns the current download progress.
// Progress only refers to the response body and does not include the headers. // Progress only refers to the response body and does not include the headers.
// If false, progress is unknown, bytes_received/total_bytes_to_be_received // If false, progress is unknown, bytes_received/total_bytes_to_be_received

@ -5,13 +5,16 @@
#include "pdf/url_loader_wrapper_impl.h" #include "pdf/url_loader_wrapper_impl.h"
#include <memory> #include <memory>
#include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h" #include "base/check_op.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/logging.h" #include "ppapi/cpp/logging.h"
#include "ppapi/cpp/url_request_info.h" #include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/url_response_info.h" #include "ppapi/cpp/url_response_info.h"
@ -99,21 +102,12 @@ bool IsDoubleEndLineAtEnd(const char* buffer, int size) {
URLLoaderWrapperImpl::URLLoaderWrapperImpl(pp::Instance* plugin_instance, URLLoaderWrapperImpl::URLLoaderWrapperImpl(pp::Instance* plugin_instance,
const pp::URLLoader& url_loader) const pp::URLLoader& url_loader)
: plugin_instance_(plugin_instance), : plugin_instance_(plugin_instance), url_loader_(url_loader) {
url_loader_(url_loader),
callback_factory_(this) {
SetHeadersFromLoader(); SetHeadersFromLoader();
} }
URLLoaderWrapperImpl::~URLLoaderWrapperImpl() { URLLoaderWrapperImpl::~URLLoaderWrapperImpl() {
Close(); Close();
// We should call callbacks to prevent memory leaks.
// The callbacks don't do anything, because the objects that created the
// callbacks have been destroyed.
if (!did_open_callback_.IsOptional())
did_open_callback_.RunAndClear(-1);
if (!did_read_callback_.IsOptional())
did_read_callback_.RunAndClear(-1);
} }
int URLLoaderWrapperImpl::GetContentLength() const { int URLLoaderWrapperImpl::GetContentLength() const {
@ -165,35 +159,35 @@ void URLLoaderWrapperImpl::OpenRange(const std::string& url,
const std::string& referrer_url, const std::string& referrer_url,
uint32_t position, uint32_t position,
uint32_t size, uint32_t size,
const pp::CompletionCallback& cc) { ResultCallback callback) {
did_open_callback_ = cc; pp::CompletionCallback cc = PPCompletionCallbackFromResultCallback(
pp::CompletionCallback callback = base::BindOnce(&URLLoaderWrapperImpl::DidOpen, weak_factory_.GetWeakPtr(),
callback_factory_.NewCallback(&URLLoaderWrapperImpl::DidOpen); std::move(callback)));
int rv = url_loader_.Open( int rv = url_loader_.Open(
MakeRangeRequest(plugin_instance_, url, referrer_url, position, size), MakeRangeRequest(plugin_instance_, url, referrer_url, position, size),
callback); cc);
if (rv != PP_OK_COMPLETIONPENDING) if (rv != PP_OK_COMPLETIONPENDING)
callback.Run(rv); cc.Run(rv);
} }
void URLLoaderWrapperImpl::ReadResponseBody(char* buffer, void URLLoaderWrapperImpl::ReadResponseBody(char* buffer,
int buffer_size, int buffer_size,
const pp::CompletionCallback& cc) { ResultCallback callback) {
did_read_callback_ = cc;
buffer_ = buffer; buffer_ = buffer;
buffer_size_ = buffer_size; buffer_size_ = buffer_size;
read_starter_.Start( read_starter_.Start(
FROM_HERE, kReadDelayMs, FROM_HERE, kReadDelayMs,
base::BindOnce(&URLLoaderWrapperImpl::ReadResponseBodyImpl, base::BindOnce(&URLLoaderWrapperImpl::ReadResponseBodyImpl,
base::Unretained(this))); base::Unretained(this), std::move(callback)));
} }
void URLLoaderWrapperImpl::ReadResponseBodyImpl() { void URLLoaderWrapperImpl::ReadResponseBodyImpl(ResultCallback callback) {
pp::CompletionCallback callback = pp::CompletionCallback cc = PPCompletionCallbackFromResultCallback(
callback_factory_.NewCallback(&URLLoaderWrapperImpl::DidRead); base::BindOnce(&URLLoaderWrapperImpl::DidRead, weak_factory_.GetWeakPtr(),
int rv = url_loader_.ReadResponseBody(buffer_, buffer_size_, callback); std::move(callback)));
int rv = url_loader_.ReadResponseBody(buffer_, buffer_size_, cc);
if (rv != PP_OK_COMPLETIONPENDING) { if (rv != PP_OK_COMPLETIONPENDING) {
callback.Run(rv); cc.Run(rv);
} }
} }
@ -255,12 +249,12 @@ void URLLoaderWrapperImpl::ParseHeaders() {
} }
} }
void URLLoaderWrapperImpl::DidOpen(int32_t result) { void URLLoaderWrapperImpl::DidOpen(ResultCallback callback, int32_t result) {
SetHeadersFromLoader(); SetHeadersFromLoader();
did_open_callback_.RunAndClear(result); std::move(callback).Run(result);
} }
void URLLoaderWrapperImpl::DidRead(int32_t result) { void URLLoaderWrapperImpl::DidRead(ResultCallback callback, int32_t result) {
if (multi_part_processed_) { if (multi_part_processed_) {
// Reset this flag so we look inside the buffer in calls of DidRead for this // Reset this flag so we look inside the buffer in calls of DidRead for this
// response only once. Note that this code DOES NOT handle multi part // response only once. Note that this code DOES NOT handle multi part
@ -269,12 +263,12 @@ void URLLoaderWrapperImpl::DidRead(int32_t result) {
is_multipart_ = false; is_multipart_ = false;
} }
if (result <= 0 || !is_multipart_) { if (result <= 0 || !is_multipart_) {
did_read_callback_.RunAndClear(result); std::move(callback).Run(result);
return; return;
} }
if (result <= 2) { if (result <= 2) {
// TODO(art-snake): Accumulate data for parse headers. // TODO(art-snake): Accumulate data for parse headers.
did_read_callback_.RunAndClear(result); std::move(callback).Run(result);
return; return;
} }
@ -297,12 +291,12 @@ void URLLoaderWrapperImpl::DidRead(int32_t result) {
result = length; result = length;
if (result == 0) { if (result == 0) {
// Continue receiving. // Continue receiving.
return ReadResponseBodyImpl(); return ReadResponseBodyImpl(std::move(callback));
} }
DCHECK_GT(result, 0); DCHECK_GT(result, 0);
memmove(buffer_, start, result); memmove(buffer_, start, result);
did_read_callback_.RunAndClear(result); std::move(callback).Run(result);
} }
void URLLoaderWrapperImpl::SetHeadersFromLoader() { void URLLoaderWrapperImpl::SetHeadersFromLoader() {

@ -5,14 +5,16 @@
#ifndef PDF_URL_LOADER_WRAPPER_IMPL_H_ #ifndef PDF_URL_LOADER_WRAPPER_IMPL_H_
#define PDF_URL_LOADER_WRAPPER_IMPL_H_ #define PDF_URL_LOADER_WRAPPER_IMPL_H_
#include <stdint.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include "base/macros.h" #include "base/memory/weak_ptr.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "pdf/ppapi_migration/callback.h"
#include "pdf/url_loader_wrapper.h" #include "pdf/url_loader_wrapper.h"
#include "ppapi/cpp/url_loader.h" #include "ppapi/cpp/url_loader.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ui/gfx/range/range.h" #include "ui/gfx/range/range.h"
namespace pp { namespace pp {
@ -25,6 +27,8 @@ class URLLoaderWrapperImpl : public URLLoaderWrapper {
public: public:
URLLoaderWrapperImpl(pp::Instance* plugin_instance, URLLoaderWrapperImpl(pp::Instance* plugin_instance,
const pp::URLLoader& url_loader); const pp::URLLoader& url_loader);
URLLoaderWrapperImpl(const URLLoaderWrapperImpl&) = delete;
URLLoaderWrapperImpl& operator=(const URLLoaderWrapperImpl&) = delete;
~URLLoaderWrapperImpl() override; ~URLLoaderWrapperImpl() override;
// URLLoaderWrapper overrides: // URLLoaderWrapper overrides:
@ -43,20 +47,20 @@ class URLLoaderWrapperImpl : public URLLoaderWrapper {
const std::string& referrer_url, const std::string& referrer_url,
uint32_t position, uint32_t position,
uint32_t size, uint32_t size,
const pp::CompletionCallback& cc) override; ResultCallback callback) override;
void ReadResponseBody(char* buffer, void ReadResponseBody(char* buffer,
int buffer_size, int buffer_size,
const pp::CompletionCallback& cc) override; ResultCallback callback) override;
void SetResponseHeaders(const std::string& response_headers); void SetResponseHeaders(const std::string& response_headers);
private: private:
void SetHeadersFromLoader(); void SetHeadersFromLoader();
void ParseHeaders(); void ParseHeaders();
void DidOpen(int32_t result); void DidOpen(ResultCallback callback, int32_t result);
void DidRead(int32_t result); void DidRead(ResultCallback callback, int32_t result);
void ReadResponseBodyImpl(); void ReadResponseBodyImpl(ResultCallback callback);
pp::Instance* const plugin_instance_; pp::Instance* const plugin_instance_;
pp::URLLoader url_loader_; pp::URLLoader url_loader_;
@ -74,13 +78,9 @@ class URLLoaderWrapperImpl : public URLLoaderWrapper {
uint32_t buffer_size_ = 0; uint32_t buffer_size_ = 0;
bool multi_part_processed_ = false; bool multi_part_processed_ = false;
pp::CompletionCallback did_open_callback_;
pp::CompletionCallback did_read_callback_;
pp::CompletionCallbackFactory<URLLoaderWrapperImpl> callback_factory_;
base::OneShotTimer read_starter_; base::OneShotTimer read_starter_;
DISALLOW_COPY_AND_ASSIGN(URLLoaderWrapperImpl); base::WeakPtrFactory<URLLoaderWrapperImpl> weak_factory_{this};
}; };
} // namespace chrome_pdf } // namespace chrome_pdf