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

Side by Side Diff: content/child/blob_storage/blob_transport_controller.cc

Issue 1853333003: [BlobAsync] Faster shortcuttin, make renderer controller leaky & alive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/blob_storage/blob_transport_controller.h" 5 #include "content/child/blob_storage/blob_transport_controller.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/memory/scoped_vector.h" 11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/shared_memory.h" 12 #include "base/memory/shared_memory.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "content/child/blob_storage/blob_consolidation.h" 15 #include "content/child/blob_storage/blob_consolidation.h"
16 #include "content/child/child_process.h" 16 #include "content/child/child_process.h"
17 #include "content/child/thread_safe_sender.h" 17 #include "content/child/thread_safe_sender.h"
18 #include "content/common/fileapi/webblob_messages.h" 18 #include "content/common/fileapi/webblob_messages.h"
19 #include "ipc/ipc_sender.h" 19 #include "ipc/ipc_sender.h"
20 #include "storage/common/blob_storage/blob_item_bytes_request.h" 20 #include "storage/common/blob_storage/blob_item_bytes_request.h"
21 #include "storage/common/blob_storage/blob_item_bytes_response.h" 21 #include "storage/common/blob_storage/blob_item_bytes_response.h"
22 #include "storage/common/data_element.h" 22 #include "storage/common/data_element.h"
23 23
24 using base::SharedMemory; 24 using base::SharedMemory;
25 using base::SharedMemoryHandle; 25 using base::SharedMemoryHandle;
26 using storage::BlobItemBytesRequest; 26 using storage::BlobItemBytesRequest;
27 using storage::BlobItemBytesResponse; 27 using storage::BlobItemBytesResponse;
28 using storage::IPCBlobItemRequestStrategy; 28 using storage::IPCBlobItemRequestStrategy;
29 using storage::DataElement; 29 using storage::DataElement;
30 using storage::kBlobStorageIPCThresholdBytes;
30 31
31 namespace content { 32 namespace content {
32 33
33 using storage::IPCBlobCreationCancelCode; 34 using storage::IPCBlobCreationCancelCode;
34 35
35 using ConsolidatedItem = BlobConsolidation::ConsolidatedItem; 36 using ConsolidatedItem = BlobConsolidation::ConsolidatedItem;
36 using ReadStatus = BlobConsolidation::ReadStatus; 37 using ReadStatus = BlobConsolidation::ReadStatus;
37 38
38 namespace { 39 namespace {
39 const size_t kLargeThresholdBytes = 250 * 1024; 40 static base::LazyInstance<BlobTransportController>::Leaky g_controller =
40 static base::LazyInstance<BlobTransportController> g_controller =
41 LAZY_INSTANCE_INITIALIZER; 41 LAZY_INSTANCE_INITIALIZER;
42 42
43 // This keeps the process alive while blobs are being transferred. 43 // This keeps the process alive while blobs are being transferred.
44 void IncChildProcessRefCount() { 44 void IncChildProcessRefCount() {
45 ChildProcess::current()->AddRefProcess(); 45 ChildProcess::current()->AddRefProcess();
46 } 46 }
47 47
48 void DecChildProcessRefCount() { 48 void DecChildProcessRefCount() {
49 ChildProcess::current()->ReleaseProcess(); 49 ChildProcess::current()->ReleaseProcess();
50 } 50 }
51 } // namespace 51 } // namespace
52 52
53 BlobTransportController* BlobTransportController::GetInstance() { 53 BlobTransportController* BlobTransportController::GetInstance() {
54 return g_controller.Pointer(); 54 return g_controller.Pointer();
55 } 55 }
56 56
57 BlobTransportController::~BlobTransportController() {} 57 // static
58
59 void BlobTransportController::InitiateBlobTransfer( 58 void BlobTransportController::InitiateBlobTransfer(
60 const std::string& uuid, 59 const std::string& uuid,
61 scoped_ptr<BlobConsolidation> consolidation, 60 scoped_ptr<BlobConsolidation> consolidation,
62 IPC::Sender* sender, 61 scoped_refptr<ThreadSafeSender> sender,
62 base::SingleThreadTaskRunner* io_runner,
63 scoped_refptr<base::SingleThreadTaskRunner> main_runner) { 63 scoped_refptr<base::SingleThreadTaskRunner> main_runner) {
64 if (main_runner->BelongsToCurrentThread()) {
65 IncChildProcessRefCount();
66 } else {
67 main_runner->PostTask(FROM_HERE, base::Bind(&IncChildProcessRefCount));
68 }
69
70 // If we fit in IPC, then shortcut our process by sending the descriptions
71 // right away. We schedule our task on the IO thread first as an extra
72 // precaution that we will store the consolidation object before we get any
73 // response from the browser.
64 BlobConsolidation* consolidation_ptr = consolidation.get(); 74 BlobConsolidation* consolidation_ptr = consolidation.get();
65 if (blob_storage_.empty()) { 75 IPC::Sender* sender_ptr = sender.get();
66 main_thread_runner_ = std::move(main_runner); 76 bool presend_descriptions =
67 main_thread_runner_->PostTask(FROM_HERE, 77 consolidation->total_memory() <= kBlobStorageIPCThresholdBytes;
68 base::Bind(&IncChildProcessRefCount)); 78 io_runner->PostTask(
kinuko 2016/04/05 09:54:45 Per comment this function could be called on any t
dmurph 2016/04/05 18:24:23 I changed the comment, we expect to be called on t
79 FROM_HERE,
80 base::Bind(&BlobTransportController::InitiateBlobTransferOnIOThread,
81 base::Unretained(BlobTransportController::GetInstance()), uuid,
82 base::Passed(std::move(consolidation)),
83 base::Passed(std::move(sender)), presend_descriptions,
kinuko 2016/04/05 09:54:45 nit: why we move sender here while it's thread-saf
dmurph 2016/04/05 18:24:24 Passing sender by value so we're technically corre
michaeln 2016/04/05 18:49:58 I dont think use of sender_ptr is completely safe
dmurph 2016/04/05 19:19:24 Done.
84 base::Passed(std::move(main_runner))));
85 if (presend_descriptions) {
86 std::vector<storage::DataElement> descriptions;
87 BlobTransportController::GetDescriptions(
88 consolidation_ptr, kBlobStorageIPCThresholdBytes, &descriptions);
89 sender_ptr->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions));
kinuko 2016/04/05 09:54:45 I'm a bit confused, which thread are we supposed t
dmurph 2016/04/05 18:24:23 There was a performance regression (see https://bu
michaeln 2016/04/05 18:49:58 You could try to always send the StartMsg on the c
dmurph 2016/04/05 19:19:24 Done. I like this better.
69 } 90 }
70 blob_storage_[uuid] = std::move(consolidation);
71 std::vector<storage::DataElement> descriptions;
72 GetDescriptions(consolidation_ptr, kLargeThresholdBytes, &descriptions);
73 sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions));
74 } 91 }
75 92
76 void BlobTransportController::OnMemoryRequest( 93 void BlobTransportController::OnMemoryRequest(
77 const std::string& uuid, 94 const std::string& uuid,
78 const std::vector<storage::BlobItemBytesRequest>& requests, 95 const std::vector<storage::BlobItemBytesRequest>& requests,
79 std::vector<base::SharedMemoryHandle>* memory_handles, 96 std::vector<base::SharedMemoryHandle>* memory_handles,
80 const std::vector<IPC::PlatformFileForTransit>& file_handles, 97 const std::vector<IPC::PlatformFileForTransit>& file_handles,
81 IPC::Sender* sender) { 98 IPC::Sender* sender) {
82 std::vector<storage::BlobItemBytesResponse> responses; 99 std::vector<storage::BlobItemBytesResponse> responses;
83 ResponsesStatus status = 100 ResponsesStatus status =
(...skipping 24 matching lines...) Expand all
108 storage::IPCBlobCreationCancelCode code) { 125 storage::IPCBlobCreationCancelCode code) {
109 DVLOG(1) << "Received blob cancel for blob " << uuid 126 DVLOG(1) << "Received blob cancel for blob " << uuid
110 << " with code: " << static_cast<int>(code); 127 << " with code: " << static_cast<int>(code);
111 ReleaseBlobConsolidation(uuid); 128 ReleaseBlobConsolidation(uuid);
112 } 129 }
113 130
114 void BlobTransportController::OnDone(const std::string& uuid) { 131 void BlobTransportController::OnDone(const std::string& uuid) {
115 ReleaseBlobConsolidation(uuid); 132 ReleaseBlobConsolidation(uuid);
116 } 133 }
117 134
118 void BlobTransportController::ClearForTesting() { 135 // static
119 if (!blob_storage_.empty() && main_thread_runner_) {
120 main_thread_runner_->PostTask(FROM_HERE,
121 base::Bind(&DecChildProcessRefCount));
122 }
123 blob_storage_.clear();
124 }
125
126 BlobTransportController::BlobTransportController() {}
127
128 void BlobTransportController::GetDescriptions( 136 void BlobTransportController::GetDescriptions(
129 BlobConsolidation* consolidation, 137 BlobConsolidation* consolidation,
130 size_t max_data_population, 138 size_t max_data_population,
131 std::vector<storage::DataElement>* out) { 139 std::vector<storage::DataElement>* out) {
132 DCHECK(out->empty()); 140 DCHECK(out->empty());
133 DCHECK(consolidation); 141 DCHECK(consolidation);
134 const auto& consolidated_items = consolidation->consolidated_items(); 142 const auto& consolidated_items = consolidation->consolidated_items();
135 143
136 size_t current_memory_population = 0; 144 size_t current_memory_population = 0;
137 size_t current_item = 0; 145 size_t current_item = 0;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 } 179 }
172 case DataElement::TYPE_DISK_CACHE_ENTRY: 180 case DataElement::TYPE_DISK_CACHE_ENTRY:
173 case DataElement::TYPE_BYTES_DESCRIPTION: 181 case DataElement::TYPE_BYTES_DESCRIPTION:
174 case DataElement::TYPE_UNKNOWN: 182 case DataElement::TYPE_UNKNOWN:
175 NOTREACHED(); 183 NOTREACHED();
176 } 184 }
177 ++current_item; 185 ++current_item;
178 } 186 }
179 } 187 }
180 188
189 BlobTransportController::BlobTransportController() {}
190
191 BlobTransportController::~BlobTransportController() {}
192
193 void BlobTransportController::ClearForTesting() {
194 if (!blob_storage_.empty() && main_thread_runner_) {
195 main_thread_runner_->PostTask(FROM_HERE,
196 base::Bind(&DecChildProcessRefCount));
197 }
198 blob_storage_.clear();
199 }
200
201 void BlobTransportController::InitiateBlobTransferOnIOThread(
202 const std::string& uuid,
203 scoped_ptr<BlobConsolidation> consolidation,
204 scoped_refptr<ThreadSafeSender> sender,
205 bool sent_descriptions,
206 scoped_refptr<base::SingleThreadTaskRunner> main_runner) {
207 if (!main_thread_runner_.get()) {
208 main_thread_runner_ = std::move(main_runner);
209 }
210 BlobConsolidation* consolidation_ptr = consolidation.get();
211 blob_storage_[uuid] = std::move(consolidation);
212 if (!sent_descriptions) {
213 std::vector<storage::DataElement> descriptions;
214 GetDescriptions(consolidation_ptr, kBlobStorageIPCThresholdBytes,
215 &descriptions);
216 sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions));
217 }
218 }
219
181 BlobTransportController::ResponsesStatus BlobTransportController::GetResponses( 220 BlobTransportController::ResponsesStatus BlobTransportController::GetResponses(
182 const std::string& uuid, 221 const std::string& uuid,
183 const std::vector<BlobItemBytesRequest>& requests, 222 const std::vector<BlobItemBytesRequest>& requests,
184 std::vector<SharedMemoryHandle>* memory_handles, 223 std::vector<SharedMemoryHandle>* memory_handles,
185 const std::vector<IPC::PlatformFileForTransit>& file_handles, 224 const std::vector<IPC::PlatformFileForTransit>& file_handles,
186 std::vector<BlobItemBytesResponse>* out) { 225 std::vector<BlobItemBytesResponse>* out) {
187 DCHECK(out->empty()); 226 DCHECK(out->empty());
188 auto it = blob_storage_.find(uuid); 227 auto it = blob_storage_.find(uuid);
189 if (it == blob_storage_.end()) 228 if (it == blob_storage_.end())
190 return ResponsesStatus::BLOB_NOT_FOUND; 229 return ResponsesStatus::BLOB_NOT_FOUND;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 case IPCBlobItemRequestStrategy::UNKNOWN: 287 case IPCBlobItemRequestStrategy::UNKNOWN:
249 NOTREACHED(); 288 NOTREACHED();
250 break; 289 break;
251 } 290 }
252 } 291 }
253 return ResponsesStatus::SUCCESS; 292 return ResponsesStatus::SUCCESS;
254 } 293 }
255 294
256 void BlobTransportController::ReleaseBlobConsolidation( 295 void BlobTransportController::ReleaseBlobConsolidation(
257 const std::string& uuid) { 296 const std::string& uuid) {
258 // If we erased something and we're now empty, release the child process 297 if (blob_storage_.erase(uuid)) {
259 // ref count and deref the main thread runner.
260 if (blob_storage_.erase(uuid) && blob_storage_.empty()) {
261 main_thread_runner_->PostTask(FROM_HERE, 298 main_thread_runner_->PostTask(FROM_HERE,
262 base::Bind(&DecChildProcessRefCount)); 299 base::Bind(&DecChildProcessRefCount));
263 main_thread_runner_ = nullptr;
264 } 300 }
265 } 301 }
266 302
267 } // namespace content 303 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698