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

Side by Side Diff: third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp

Issue 2892953006: WIP POC blob transport over mojo
Patch Set: pass mojo blobs over ipc Created 3 years, 6 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/blob/BlobBytesProvider.h"
6
7 #include "platform/wtf/Functional.h"
8 #include "public/platform/Platform.h"
9
10 namespace blink {
11
12 namespace {
13
14 class BlobBytesStreamer {
15 public:
16 BlobBytesStreamer(Vector<RefPtr<RawData>> data,
17 mojo::ScopedDataPipeProducerHandle pipe)
18 : data_(std::move(data)),
19 pipe_(std::move(pipe)),
20 watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
21 watcher_.Watch(pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
22 ConvertToBaseCallback(WTF::Bind(
23 &BlobBytesStreamer::OnWritable, WTF::Unretained(this))));
24 }
25
26 void OnWritable(MojoResult result) {
27 if (result == MOJO_RESULT_CANCELLED ||
28 result == MOJO_RESULT_FAILED_PRECONDITION) {
29 LOG(INFO) << "Deleting, current item: " << current_item_
30 << ", current pos: " << current_item_offset_;
31 delete this;
32 return;
33 }
34 DCHECK_EQ(result, MOJO_RESULT_OK);
35
36 while (true) {
37 uint32_t num_bytes =
38 data_[current_item_]->length() - current_item_offset_;
39 MojoResult write_result = mojo::WriteDataRaw(
40 pipe_.get(), data_[current_item_]->data() + current_item_offset_,
41 &num_bytes, MOJO_WRITE_DATA_FLAG_NONE);
42 if (write_result == MOJO_RESULT_OK) {
43 LOG(INFO) << "Wrote " << num_bytes;
44 current_item_offset_ += num_bytes;
45 if (current_item_offset_ >= data_[current_item_]->length()) {
46 current_item_++;
47 if (current_item_ >= int(data_.size())) {
48 // Send all items completely, done.
49 LOG(INFO) << "Done writing, deleting self";
50 delete this;
51 return;
52 }
53 }
54 } else if (write_result == MOJO_RESULT_SHOULD_WAIT) {
55 break;
56 } else {
57 // Something went wrong.
58 delete this;
59 return;
60 }
61 }
62 }
63
64 private:
65 int current_item_ = 0;
66 size_t current_item_offset_ = 0;
67 Vector<RefPtr<RawData>> data_;
68
69 mojo::ScopedDataPipeProducerHandle pipe_;
70 mojo::SimpleWatcher watcher_;
71 };
72
73 Time TimeFromDouble(double dt) {
74 if (dt == 0 || std::isnan(dt))
75 return Time();
76 return Time::FromSeconds(base::Time::kTimeTToMicrosecondsOffset / 1000000 +
77 dt);
78 }
79
80 } // namespace
81
82 BlobBytesProvider::BlobBytesProvider(RefPtr<RawData> data) {
83 Platform::Current()->IncProcessRefCount();
84 data_.push_back(std::move(data));
85 }
86
87 BlobBytesProvider::~BlobBytesProvider() {
88 Platform::Current()->DecProcessRefCount();
89 LOG(INFO) << "Destroying bytes provider for " << uuid;
90 }
91
92 void BlobBytesProvider::AppendData(RefPtr<RawData> data) {
93 data_.push_back(std::move(data));
94 }
95
96 void BlobBytesProvider::RequestAsStream(
97 mojo::ScopedDataPipeProducerHandle pipe) {
98 LOG(INFO) << "Data being requested as stream for " << uuid;
99 // Will self delete when done.
100 new BlobBytesStreamer(data_, std::move(pipe));
101 }
102
103 void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
104 uint64_t source_size,
105 base::File file,
106 uint64_t file_offset,
107 RequestAsFileCallback callback) {
108 LOG(INFO) << "Data being requested as files" << uuid;
109 // TODO(mek): Do on correct thread
110 if (!file.IsValid()) {
111 std::move(callback).Run(WTF::nullopt);
112 return;
113 }
114
115 int64_t seek_distance =
116 file.Seek(base::File::FROM_BEGIN, SafeCast<int64_t>(file_offset));
117 bool seek_failed = seek_distance < 0;
118 // histogram Storage.Blob.RendererFileSeekFailed
119 if (seek_failed) {
120 std::move(callback).Run(WTF::nullopt);
121 return;
122 }
123
124 // TODO(mek): More efficient way to find beginning.
125 uint64_t offset = 0;
126 for (const RefPtr<RawData>& data : data_) {
127 if (offset + data->length() > source_offset) {
128 uint64_t data_offset = source_offset - offset;
129 uint64_t data_size = std::min(data->length() - data_offset,
130 source_size - offset - source_offset);
131 size_t written = 0;
132 while (written < data_size) {
133 size_t writing_size = data_size - written;
134 int actual_written =
135 file.WriteAtCurrentPos(data->data() + data_offset + written,
136 static_cast<int>(writing_size));
137 bool write_failed = actual_written < 0;
138 // histogram Storage.Blob.RendererFileWriteFailed
139 if (write_failed) {
140 std::move(callback).Run(WTF::nullopt);
141 return;
142 }
143 written += actual_written;
144 }
145 }
146 offset += data->length();
147 }
148
149 if (!file.Flush()) {
150 std::move(callback).Run(WTF::nullopt);
151 return;
152 }
153 base::File::Info info;
154 if (!file.GetInfo(&info)) {
155 std::move(callback).Run(WTF::nullopt);
156 return;
157 }
158 LOG(INFO) << "About to call final callback " << info.last_modified;
159 std::move(callback).Run(TimeFromDouble(info.last_modified.ToDoubleT()));
160 }
161
162 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/blob/BlobBytesProvider.h ('k') | third_party/WebKit/Source/platform/blob/BlobData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698