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

Side by Side Diff: content/browser/blob_storage/blob_dispatcher_host.cc

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: half of comments Created 4 years, 4 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/browser/blob_storage/blob_dispatcher_host.h" 5 #include "content/browser/blob_storage/blob_dispatcher_host.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "content/browser/bad_message.h" 11 #include "content/browser/bad_message.h"
12 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 12 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
13 #include "content/browser/child_process_security_policy_impl.h" 13 #include "content/browser/child_process_security_policy_impl.h"
14 #include "content/browser/fileapi/browser_file_system_helper.h" 14 #include "content/browser/fileapi/browser_file_system_helper.h"
15 #include "content/common/fileapi/webblob_messages.h" 15 #include "content/common/fileapi/webblob_messages.h"
16 #include "ipc/ipc_platform_file.h" 16 #include "ipc/ipc_platform_file.h"
17 #include "storage/browser/blob/blob_data_handle.h"
17 #include "storage/browser/blob/blob_storage_context.h" 18 #include "storage/browser/blob/blob_storage_context.h"
18 #include "storage/browser/blob/blob_transport_result.h"
19 #include "storage/browser/fileapi/file_system_context.h" 19 #include "storage/browser/fileapi/file_system_context.h"
20 #include "storage/browser/fileapi/file_system_url.h" 20 #include "storage/browser/fileapi/file_system_url.h"
21 #include "storage/browser/blob/internal_blob_data.h"
21 #include "storage/common/blob_storage/blob_item_bytes_request.h" 22 #include "storage/common/blob_storage/blob_item_bytes_request.h"
22 #include "storage/common/blob_storage/blob_item_bytes_response.h" 23 #include "storage/common/blob_storage/blob_item_bytes_response.h"
23 #include "storage/common/data_element.h" 24 #include "storage/common/data_element.h"
24 #include "url/gurl.h" 25 #include "url/gurl.h"
25 26
26 using storage::BlobStorageContext; 27 using storage::BlobStorageContext;
27 using storage::BlobStorageRegistry; 28 using storage::BlobStorageRegistry;
28 using storage::BlobTransportResult; 29 using storage::BlobStatus;
29 using storage::DataElement; 30 using storage::DataElement;
30 using storage::IPCBlobCreationCancelCode;
31 using storage::FileSystemURL; 31 using storage::FileSystemURL;
32 32
33 namespace content { 33 namespace content {
34 namespace { 34 namespace {
35 35
36 // These are used for UMA stats, don't change. 36 // These are used for UMA stats, don't change.
37 enum RefcountOperation { 37 enum RefcountOperation {
38 BDH_DECREMENT = 0, 38 BDH_DECREMENT = 0,
39 BDH_INCREMENT, 39 BDH_INCREMENT,
40 BDH_TRACING_ENUM_LAST 40 BDH_TRACING_ENUM_LAST
(...skipping 16 matching lines...) Expand all
57 57
58 void BlobDispatcherHost::OnChannelClosing() { 58 void BlobDispatcherHost::OnChannelClosing() {
59 ClearHostFromBlobStorageContext(); 59 ClearHostFromBlobStorageContext();
60 public_blob_urls_.clear(); 60 public_blob_urls_.clear();
61 blobs_inuse_map_.clear(); 61 blobs_inuse_map_.clear();
62 } 62 }
63 63
64 bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message) { 64 bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message) {
65 bool handled = true; 65 bool handled = true;
66 IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message) 66 IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message)
67 IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlobUUID, OnRegisterBlobUUID) 67 IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlob, OnRegisterBlob)
68 IPC_MESSAGE_HANDLER(BlobStorageMsg_StartBuildingBlob, OnStartBuildingBlob)
69 IPC_MESSAGE_HANDLER(BlobStorageMsg_MemoryItemResponse, OnMemoryItemResponse) 68 IPC_MESSAGE_HANDLER(BlobStorageMsg_MemoryItemResponse, OnMemoryItemResponse)
70 IPC_MESSAGE_HANDLER(BlobStorageMsg_CancelBuildingBlob, OnCancelBuildingBlob) 69 IPC_MESSAGE_HANDLER(BlobStorageMsg_SendBlobStatus, OnCancelBuildingBob)
71 IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount, OnIncrementBlobRefCount) 70 IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount, OnIncrementBlobRefCount)
72 IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount, OnDecrementBlobRefCount) 71 IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount, OnDecrementBlobRefCount)
73 IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL, OnRegisterPublicBlobURL) 72 IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL, OnRegisterPublicBlobURL)
74 IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL) 73 IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
75 IPC_MESSAGE_UNHANDLED(handled = false) 74 IPC_MESSAGE_UNHANDLED(handled = false)
76 IPC_END_MESSAGE_MAP() 75 IPC_END_MESSAGE_MAP()
77 return handled; 76 return handled;
78 } 77 }
79 78
80 void BlobDispatcherHost::OnRegisterBlobUUID( 79 void BlobDispatcherHost::OnRegisterBlob(
81 const std::string& uuid, 80 const std::string& uuid,
82 const std::string& content_type, 81 const std::string& content_type,
83 const std::string& content_disposition, 82 const std::string& content_disposition,
84 const std::set<std::string>& referenced_blob_uuids) { 83 const std::vector<storage::DataElement>& descriptions) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO); 84 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 BlobStorageContext* context = this->context(); 85 BlobStorageContext* context = this->context();
87 if (uuid.empty() || context->registry().HasEntry(uuid) || 86 if (uuid.empty() || context->registry().HasEntry(uuid) ||
88 async_builder_.IsBeingBuilt(uuid)) { 87 async_builder_.IsBeingBuilt(uuid)) {
89 bad_message::ReceivedBadMessage(this, bad_message::BDH_UUID_REGISTERED); 88 bad_message::ReceivedBadMessage(this, bad_message::BDH_UUID_REGISTERED);
90 return; 89 return;
91 } 90 }
92 blobs_inuse_map_[uuid] = 1;
93 BlobTransportResult result = async_builder_.RegisterBlobUUID(
94 uuid, content_type, content_disposition, referenced_blob_uuids, context);
95 switch (result) {
96 case BlobTransportResult::BAD_IPC:
97 blobs_inuse_map_.erase(uuid);
98 bad_message::ReceivedBadMessage(this,
99 bad_message::BDH_CONSTRUCTION_FAILED);
100 break;
101 case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN:
102 // The async builder builds the blob as broken, and we just need to send
103 // the cancel message back to the renderer.
104 Send(new BlobStorageMsg_CancelBuildingBlob(
105 uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN));
106 break;
107 case BlobTransportResult::DONE:
108 break;
109 case BlobTransportResult::CANCEL_MEMORY_FULL:
110 case BlobTransportResult::CANCEL_FILE_ERROR:
111 case BlobTransportResult::CANCEL_UNKNOWN:
112 case BlobTransportResult::PENDING_RESPONSES:
113 NOTREACHED();
114 break;
115 }
116 }
117
118 void BlobDispatcherHost::OnStartBuildingBlob(
119 const std::string& uuid,
120 const std::vector<storage::DataElement>& descriptions) {
121 DCHECK_CURRENTLY_ON(BrowserThread::IO);
122 if (uuid.empty()) {
123 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
124 return;
125 }
126 BlobStorageContext* context = this->context();
127 const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid);
128 if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) {
129 // We ignore messages for blobs that don't exist to handle the case where
130 // the renderer de-refs a blob that we're still constructing, and there are
131 // no references to that blob. We ignore broken as well, in the case where
132 // we decided to break a blob after RegisterBlobUUID is called.
133 // Second, if the last dereference of the blob happened on a different host,
134 // then we still haven't gotten rid of the 'building' state in the original
135 // host. So we call cancel, and send the message just in case that happens.
136 if (async_builder_.IsBeingBuilt(uuid)) {
137 async_builder_.CancelBuildingBlob(
138 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
139 context);
140 Send(new BlobStorageMsg_CancelBuildingBlob(
141 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
142 }
143 return;
144 }
145 if (!async_builder_.IsBeingBuilt(uuid)) {
146 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC);
147 return;
148 }
149 91
150 ChildProcessSecurityPolicyImpl* security_policy = 92 ChildProcessSecurityPolicyImpl* security_policy =
151 ChildProcessSecurityPolicyImpl::GetInstance(); 93 ChildProcessSecurityPolicyImpl::GetInstance();
152 for (const DataElement& item : descriptions) { 94 for (const DataElement& item : descriptions) {
153 if (item.type() == storage::DataElement::TYPE_FILE_FILESYSTEM) { 95 if (item.type() == storage::DataElement::TYPE_FILE_FILESYSTEM) {
154 FileSystemURL filesystem_url( 96 FileSystemURL filesystem_url(
155 file_system_context_->CrackURL(item.filesystem_url())); 97 file_system_context_->CrackURL(item.filesystem_url()));
156 if (!FileSystemURLIsValid(file_system_context_.get(), filesystem_url) || 98 if (!FileSystemURLIsValid(file_system_context_.get(), filesystem_url) ||
157 !security_policy->CanReadFileSystemFile(process_id_, 99 !security_policy->CanReadFileSystemFile(process_id_,
158 filesystem_url)) { 100 filesystem_url)) {
159 async_builder_.CancelBuildingBlob( 101 SendFinalBlobStatus(uuid, BlobStatus::ERR_FILE_WRITE_FAILED);
160 uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED, context);
161 Send(new BlobStorageMsg_CancelBuildingBlob(
162 uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED));
163 return; 102 return;
164 } 103 }
165 } 104 }
166 if (item.type() == storage::DataElement::TYPE_FILE && 105 if (item.type() == storage::DataElement::TYPE_FILE &&
167 !security_policy->CanReadFile(process_id_, item.path())) { 106 !security_policy->CanReadFile(process_id_, item.path())) {
168 async_builder_.CancelBuildingBlob( 107 SendFinalBlobStatus(uuid, BlobStatus::ERR_FILE_WRITE_FAILED);
169 uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED, context);
170 Send(new BlobStorageMsg_CancelBuildingBlob(
171 uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED));
172 return; 108 return;
173 } 109 }
174 } 110 }
111 blobs_inuse_map_[uuid] = 1;
175 112
176 // |this| owns async_builder_ so using base::Unretained(this) is safe. 113 async_builder_.RegisterBlob(
177 BlobTransportResult result = async_builder_.StartBuildingBlob( 114 uuid, content_type, content_disposition, descriptions, context,
178 uuid, descriptions, context->memory_available(), context,
179 base::Bind(&BlobDispatcherHost::SendMemoryRequest, base::Unretained(this), 115 base::Bind(&BlobDispatcherHost::SendMemoryRequest, base::Unretained(this),
180 uuid)); 116 uuid),
181 SendIPCResponse(uuid, result); 117 base::Bind(&BlobDispatcherHost::SendFinalBlobStatus,
118 base::Unretained(this), uuid));
182 } 119 }
183 120
184 void BlobDispatcherHost::OnMemoryItemResponse( 121 void BlobDispatcherHost::OnMemoryItemResponse(
185 const std::string& uuid, 122 const std::string& uuid,
186 const std::vector<storage::BlobItemBytesResponse>& responses) { 123 const std::vector<storage::BlobItemBytesResponse>& responses) {
187 DCHECK_CURRENTLY_ON(BrowserThread::IO); 124 DCHECK_CURRENTLY_ON(BrowserThread::IO);
188 if (uuid.empty()) { 125 if (uuid.empty()) {
189 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC); 126 bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
190 return; 127 return;
191 } 128 }
192 BlobStorageContext* context = this->context(); 129 BlobStorageContext* context = this->context();
193 const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid); 130 const storage::InternalBlobData* entry = context->registry().GetEntry(uuid);
194 if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) { 131 if (!entry || BlobStatusIsError(entry->status())) {
195 // We ignore messages for blobs that don't exist to handle the case where 132 // We ignore messages for blobs that don't exist to handle the case where
196 // the renderer de-refs a blob that we're still constructing, and there are 133 // the renderer de-refs a blob that we're still constructing, and there are
197 // no references to that blob. We ignore broken as well, in the case where 134 // no references to that blob. We ignore broken as well, in the case where
198 // we decided to break a blob after sending the memory request. 135 // we decided to break a blob after sending the memory request.
199 // Note: if a blob is broken, then it can't be in the async_builder. 136 // Note: if a blob is broken, then it can't be in the async_builder.
200 // Second, if the last dereference of the blob happened on a different host, 137 // Second, if the last dereference of the blob happened on a different host,
201 // then we still haven't gotten rid of the 'building' state in the original 138 // then we still haven't gotten rid of the 'building' state in the original
202 // host. So we call cancel, and send the message just in case that happens. 139 // host. So we call cancel, and send the message just in case that happens.
203 if (async_builder_.IsBeingBuilt(uuid)) { 140 if (async_builder_.IsBeingBuilt(uuid)) {
204 async_builder_.CancelBuildingBlob( 141 async_builder_.CancelBuildingBlob(
205 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING, 142 uuid, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING, context);
206 context); 143 SendFinalBlobStatus(uuid,
207 Send(new BlobStorageMsg_CancelBuildingBlob( 144 BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING);
208 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
209 } 145 }
210 return; 146 return;
211 } 147 }
212 if (!async_builder_.IsBeingBuilt(uuid)) { 148 if (!async_builder_.IsBeingBuilt(uuid)) {
213 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC); 149 bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
214 return; 150 return;
215 } 151 }
216 BlobTransportResult result = 152 BlobStatus result =
217 async_builder_.OnMemoryResponses(uuid, responses, context); 153 async_builder_.OnMemoryResponses(uuid, responses, context);
218 SendIPCResponse(uuid, result); 154 SendFinalBlobStatus(uuid, result);
michaeln 2016/08/23 01:31:55 I thought that in some cases the result can still
219 } 155 }
220 156
221 void BlobDispatcherHost::OnCancelBuildingBlob( 157 void BlobDispatcherHost::OnCancelBuildingBob(const std::string& uuid,
222 const std::string& uuid, 158 const storage::BlobStatus code) {
223 const storage::IPCBlobCreationCancelCode code) {
224 DCHECK_CURRENTLY_ON(BrowserThread::IO); 159 DCHECK_CURRENTLY_ON(BrowserThread::IO);
225 if (uuid.empty()) { 160 if (uuid.empty()) {
226 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC); 161 bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
227 return; 162 return;
228 } 163 }
229 BlobStorageContext* context = this->context(); 164 BlobStorageContext* context = this->context();
230 const BlobStorageRegistry::Entry* entry = context->registry().GetEntry(uuid); 165 const storage::InternalBlobData* entry = context->registry().GetEntry(uuid);
231 if (!entry || entry->state == BlobStorageRegistry::BlobState::BROKEN) { 166 if (!entry || BlobStatusIsError(entry->status())) {
232 // We ignore messages for blobs that don't exist to handle the case where 167 // We ignore messages for blobs that don't exist to handle the case where
233 // the renderer de-refs a blob that we're still constructing, and there are 168 // the renderer de-refs a blob that we're still constructing, and there are
234 // no references to that blob. We ignore broken as well, in the case where 169 // no references to that blob. We ignore broken as well, in the case where
235 // we decided to break a blob and the renderer also decided to cancel. 170 // we decided to break a blob and the renderer also decided to cancel.
236 // Note: if a blob is broken, then it can't be in the async_builder. 171 // Note: if a blob is broken, then it can't be in the async_builder.
237 // Second, if the last dereference of the blob happened on a different host, 172 // Second, if the last dereference of the blob happened on a different host,
238 // then we still haven't gotten rid of the 'building' state in the original 173 // then we still haven't gotten rid of the 'building' state in the original
239 // host. So we call cancel just in case this happens. 174 // host. So we call cancel just in case this happens.
240 if (async_builder_.IsBeingBuilt(uuid)) { 175 if (async_builder_.IsBeingBuilt(uuid)) {
241 async_builder_.CancelBuildingBlob( 176 async_builder_.CancelBuildingBlob(
242 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING, 177 uuid, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING, context);
243 context);
244 } 178 }
245 return; 179 return;
246 } 180 }
247 if (!async_builder_.IsBeingBuilt(uuid)) { 181 // We should only get these messages for errors.
248 SendIPCResponse(uuid, BlobTransportResult::BAD_IPC); 182 if (!async_builder_.IsBeingBuilt(uuid) || !storage::BlobStatusIsError(code)) {
183 bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
249 return; 184 return;
250 } 185 }
251 VLOG(1) << "Blob construction of " << uuid << " cancelled by renderer. " 186 VLOG(1) << "Blob construction of " << uuid << " cancelled by renderer. "
252 << " Reason: " << static_cast<int>(code) << "."; 187 << " Reason: " << static_cast<int>(code) << ".";
253 async_builder_.CancelBuildingBlob(uuid, code, context); 188 async_builder_.CancelBuildingBlob(uuid, code, context);
254 } 189 }
255 190
256 void BlobDispatcherHost::OnIncrementBlobRefCount(const std::string& uuid) { 191 void BlobDispatcherHost::OnIncrementBlobRefCount(const std::string& uuid) {
257 DCHECK_CURRENTLY_ON(BrowserThread::IO); 192 DCHECK_CURRENTLY_ON(BrowserThread::IO);
258 BlobStorageContext* context = this->context(); 193 BlobStorageContext* context = this->context();
(...skipping 25 matching lines...) Expand all
284 } 219 }
285 BlobStorageContext* context = this->context(); 220 BlobStorageContext* context = this->context();
286 context->DecrementBlobRefCount(uuid); 221 context->DecrementBlobRefCount(uuid);
287 blobs_inuse_map_[uuid] -= 1; 222 blobs_inuse_map_[uuid] -= 1;
288 if (blobs_inuse_map_[uuid] == 0) { 223 if (blobs_inuse_map_[uuid] == 0) {
289 blobs_inuse_map_.erase(uuid); 224 blobs_inuse_map_.erase(uuid);
290 // If the blob has been deleted in the context and we're still building it, 225 // If the blob has been deleted in the context and we're still building it,
291 // this means we have no references waiting to read it. Clear the building 226 // this means we have no references waiting to read it. Clear the building
292 // state and send a cancel message to the renderer. 227 // state and send a cancel message to the renderer.
293 if (async_builder_.IsBeingBuilt(uuid) && 228 if (async_builder_.IsBeingBuilt(uuid) &&
294 !context->registry().HasEntry(uuid)) { 229 !context->registry().HasEntry(uuid)) {
michaeln 2016/08/23 01:31:55 If the final ref is dropped from a different rende
295 async_builder_.CancelBuildingBlob( 230 async_builder_.CancelBuildingBlob(
296 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING, 231 uuid, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING, context);
297 context); 232 SendFinalBlobStatus(
298 Send(new BlobStorageMsg_CancelBuildingBlob( 233 uuid, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING);
299 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING));
300 } 234 }
301 } 235 }
302 } 236 }
303 237
304 void BlobDispatcherHost::OnRegisterPublicBlobURL(const GURL& public_url, 238 void BlobDispatcherHost::OnRegisterPublicBlobURL(const GURL& public_url,
305 const std::string& uuid) { 239 const std::string& uuid) {
306 DCHECK_CURRENTLY_ON(BrowserThread::IO); 240 DCHECK_CURRENTLY_ON(BrowserThread::IO);
307 BlobStorageContext* context = this->context(); 241 BlobStorageContext* context = this->context();
308 if (uuid.empty()) { 242 if (uuid.empty()) {
309 bad_message::ReceivedBadMessage(this, 243 bad_message::ReceivedBadMessage(this,
(...skipping 24 matching lines...) Expand all
334 context()->RevokePublicBlobURL(public_url); 268 context()->RevokePublicBlobURL(public_url);
335 public_blob_urls_.erase(public_url); 269 public_blob_urls_.erase(public_url);
336 } 270 }
337 271
338 storage::BlobStorageContext* BlobDispatcherHost::context() { 272 storage::BlobStorageContext* BlobDispatcherHost::context() {
339 return blob_storage_context_->context(); 273 return blob_storage_context_->context();
340 } 274 }
341 275
342 void BlobDispatcherHost::SendMemoryRequest( 276 void BlobDispatcherHost::SendMemoryRequest(
343 const std::string& uuid, 277 const std::string& uuid,
344 std::unique_ptr<std::vector<storage::BlobItemBytesRequest>> requests, 278 std::vector<storage::BlobItemBytesRequest> requests,
345 std::unique_ptr<std::vector<base::SharedMemoryHandle>> memory_handles, 279 std::vector<base::SharedMemoryHandle> memory_handles,
346 std::unique_ptr<std::vector<base::File>> files) { 280 std::vector<base::File> files) {
347 DCHECK_CURRENTLY_ON(BrowserThread::IO); 281 DCHECK_CURRENTLY_ON(BrowserThread::IO);
348 std::vector<IPC::PlatformFileForTransit> file_handles; 282 std::vector<IPC::PlatformFileForTransit> file_handles;
349 // TODO(dmurph): Support file-backed blob transportation. 283 for (base::File& file : files) {
350 DCHECK(files->empty()); 284 file_handles.push_back(IPC::TakePlatformFileForTransit(std::move(file)));
351 Send(new BlobStorageMsg_RequestMemoryItem(uuid, *requests, *memory_handles, 285 }
286 Send(new BlobStorageMsg_RequestMemoryItem(uuid, requests, memory_handles,
352 file_handles)); 287 file_handles));
353 } 288 }
354 289
355 void BlobDispatcherHost::SendIPCResponse(const std::string& uuid, 290 void BlobDispatcherHost::SendFinalBlobStatus(const std::string& uuid,
356 storage::BlobTransportResult result) { 291 BlobStatus status) {
357 switch (result) { 292 if (storage::BlobStatusIsBadIPC(status)) {
358 case BlobTransportResult::BAD_IPC: 293 blobs_inuse_map_.erase(uuid);
359 bad_message::ReceivedBadMessage(this, 294 bad_message::ReceivedBadMessage(this, bad_message::BDH_CONSTRUCTION_FAILED);
360 bad_message::BDH_CONSTRUCTION_FAILED); 295 return;
361 return;
362 case BlobTransportResult::CANCEL_MEMORY_FULL:
363 Send(new BlobStorageMsg_CancelBuildingBlob(
364 uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY));
365 return;
366 case BlobTransportResult::CANCEL_FILE_ERROR:
367 Send(new BlobStorageMsg_CancelBuildingBlob(
368 uuid, IPCBlobCreationCancelCode::FILE_WRITE_FAILED));
369 return;
370 case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN:
371 Send(new BlobStorageMsg_CancelBuildingBlob(
372 uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN));
373 return;
374 case BlobTransportResult::CANCEL_UNKNOWN:
375 Send(new BlobStorageMsg_CancelBuildingBlob(
376 uuid, IPCBlobCreationCancelCode::UNKNOWN));
377 return;
378 case BlobTransportResult::PENDING_RESPONSES:
379 return;
380 case BlobTransportResult::DONE:
381 Send(new BlobStorageMsg_DoneBuildingBlob(uuid));
382 return;
383 } 296 }
384 NOTREACHED(); 297 DCHECK(status != BlobStatus::PENDING);
298 Send(new BlobStorageMsg_SendBlobStatus(uuid, status));
385 } 299 }
386 300
387 bool BlobDispatcherHost::IsInUseInHost(const std::string& uuid) { 301 bool BlobDispatcherHost::IsInUseInHost(const std::string& uuid) {
388 return blobs_inuse_map_.find(uuid) != blobs_inuse_map_.end(); 302 return blobs_inuse_map_.find(uuid) != blobs_inuse_map_.end();
389 } 303 }
390 304
391 bool BlobDispatcherHost::IsUrlRegisteredInHost(const GURL& blob_url) { 305 bool BlobDispatcherHost::IsUrlRegisteredInHost(const GURL& blob_url) {
392 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); 306 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
393 } 307 }
394 308
395 void BlobDispatcherHost::ClearHostFromBlobStorageContext() { 309 void BlobDispatcherHost::ClearHostFromBlobStorageContext() {
396 BlobStorageContext* context = this->context(); 310 BlobStorageContext* context = this->context();
397 for (const auto& url : public_blob_urls_) { 311 for (const auto& url : public_blob_urls_) {
398 context->RevokePublicBlobURL(url); 312 context->RevokePublicBlobURL(url);
399 } 313 }
400 for (const auto& uuid_refnum_pair : blobs_inuse_map_) { 314 for (const auto& uuid_refnum_pair : blobs_inuse_map_) {
401 for (int i = 0; i < uuid_refnum_pair.second; ++i) 315 for (int i = 0; i < uuid_refnum_pair.second; ++i)
402 context->DecrementBlobRefCount(uuid_refnum_pair.first); 316 context->DecrementBlobRefCount(uuid_refnum_pair.first);
403 } 317 }
404 async_builder_.CancelAll(context); 318 async_builder_.CancelAll(context);
405 } 319 }
406 320
407 } // namespace content 321 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698