Commit 5932c840 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Use ReadOnlyBuffer for sending frames in WebSocket

This reduces memory copies.

Bug: 991501
Change-Id: Icfd1c0c973d52a4528ec6a7364d7616328a882a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1809038Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697650}
parent df7445d3
......@@ -131,7 +131,9 @@ interface WebSocket {
// the first message. If |type| is WebSocketMessageType.TEXT, then the
// concatenation of the |data| from every frame in the message must be valid
// UTF-8. If |fin| is not set, |data| must be non-empty.
SendFrame(bool fin, WebSocketMessageType type, array<uint8> data);
SendFrame(bool fin,
WebSocketMessageType type,
mojo_base.mojom.ReadOnlyBuffer data);
// Let browser to start receiving WebSocket data frames from network stream.
// TODO(yoichio): Remove this by move Connect() after checking throttle at
......
......@@ -5,6 +5,7 @@
#include "services/network/websocket.h"
#include <inttypes.h>
#include <string.h>
#include <utility>
......@@ -419,7 +420,7 @@ const void* const WebSocket::kUserDataKey = &WebSocket::kUserDataKey;
void WebSocket::SendFrame(bool fin,
mojom::WebSocketMessageType type,
const std::vector<uint8_t>& data) {
base::span<const uint8_t> data) {
DVLOG(3) << "WebSocket::SendFrame @" << reinterpret_cast<void*>(this)
<< " fin=" << fin << " type=" << type << " data is " << data.size()
<< " bytes";
......@@ -435,7 +436,7 @@ void WebSocket::SendFrame(bool fin,
// TODO(darin): Avoid this copy.
auto data_to_pass = base::MakeRefCounted<net::IOBuffer>(data.size());
std::copy(data.begin(), data.end(), data_to_pass->data());
memcpy(data_to_pass->data(), data.data(), data.size());
channel_->SendFrame(fin, MessageTypeToOpCode(type), std::move(data_to_pass),
data.size());
......
......@@ -13,6 +13,7 @@
#include "base/component_export.h"
#include "base/containers/queue.h"
#include "base/containers/span.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
......@@ -67,7 +68,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
// mojom::WebSocket methods:
void SendFrame(bool fin,
mojom::WebSocketMessageType type,
const std::vector<uint8_t>& data) override;
base::span<const uint8_t> data) override;
void StartReceiving() override;
void StartClosingHandshake(uint16_t code, const std::string& reason) override;
......
......@@ -627,15 +627,8 @@ void WebSocketChannelImpl::SendAndAdjustQuota(
network::mojom::blink::WebSocketMessageType type,
base::span<const char> data,
uint64_t* consumed_buffered_amount) {
// TODO(darin): Avoid this copy.
Vector<uint8_t> data_to_pass;
// This cast is always valid because the data size is limited by
// sending_quota_, which is controlled by the browser process and in practice
// is always much smaller than 4GB.
// TODO(ricea): Change the type of sending_quota_ to wtf_size_t.
data_to_pass.ReserveInitialCapacity(static_cast<wtf_size_t>(data.size()));
data_to_pass.Append(data.data(), static_cast<wtf_size_t>(data.size()));
base::span<const uint8_t> data_to_pass(
reinterpret_cast<const uint8_t*>(data.data()), data.size());
websocket_->SendFrame(fin, type, data_to_pass);
sending_quota_ -= data.size();
......
......@@ -112,8 +112,10 @@ class WebSocketChannelImplTest : public PageTestBase {
void SendFrame(bool fin,
WebSocketMessageType type,
const Vector<uint8_t>& data) override {
frames_.push_back(Frame{fin, type, data});
base::span<const uint8_t> data) override {
Vector<uint8_t> data_to_pass;
data_to_pass.AppendRange(data.begin(), data.end());
frames_.push_back(Frame{fin, type, std::move(data_to_pass)});
}
void StartReceiving() override {
DCHECK(!is_start_receiving_called_);
......
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