| OLD | NEW |
| 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 <limits> | 7 #include <limits> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 BlobConsolidation* consolidation = it->second.get(); | 204 BlobConsolidation* consolidation = it->second.get(); |
| 205 const auto& consolidated_items = consolidation->consolidated_items(); | 205 const auto& consolidated_items = consolidation->consolidated_items(); |
| 206 | 206 |
| 207 std::unique_ptr<std::vector<BlobItemBytesRequest>> file_requests( | 207 std::unique_ptr<std::vector<BlobItemBytesRequest>> file_requests( |
| 208 new std::vector<BlobItemBytesRequest>()); | 208 new std::vector<BlobItemBytesRequest>()); |
| 209 | 209 |
| 210 // Since we can be writing to the same shared memory handle from multiple | 210 // Since we can be writing to the same shared memory handle from multiple |
| 211 // requests, we keep them in a vector and lazily create them. | 211 // requests, we keep them in a vector and lazily create them. |
| 212 ScopedVector<SharedMemory> opened_memory; | 212 ScopedVector<SharedMemory> opened_memory; |
| 213 opened_memory.resize(memory_handles->size()); | 213 opened_memory.resize(memory_handles->size()); |
| 214 |
| 215 // We need to calculate how much memory we expect to be writing to the memory |
| 216 // segments so we can correctly map it the first time. |
| 217 std::vector<size_t> shared_memory_sizes(memory_handles->size()); |
| 218 for (const BlobItemBytesRequest& request : requests) { |
| 219 if (request.transport_strategy != |
| 220 IPCBlobItemRequestStrategy::SHARED_MEMORY) { |
| 221 continue; |
| 222 } |
| 223 DCHECK_LT(request.handle_index, memory_handles->size()) |
| 224 << "Invalid handle index."; |
| 225 shared_memory_sizes[request.handle_index] = |
| 226 std::max<size_t>(shared_memory_sizes[request.handle_index], |
| 227 request.size + request.handle_offset); |
| 228 } |
| 229 |
| 214 for (const BlobItemBytesRequest& request : requests) { | 230 for (const BlobItemBytesRequest& request : requests) { |
| 215 DCHECK_LT(request.renderer_item_index, consolidated_items.size()) | 231 DCHECK_LT(request.renderer_item_index, consolidated_items.size()) |
| 216 << "Invalid item index"; | 232 << "Invalid item index"; |
| 217 | 233 |
| 218 const ConsolidatedItem& item = | 234 const ConsolidatedItem& item = |
| 219 consolidated_items[request.renderer_item_index]; | 235 consolidated_items[request.renderer_item_index]; |
| 220 DCHECK_LE(request.renderer_item_offset + request.size, item.length) | 236 DCHECK_LE(request.renderer_item_offset + request.size, item.length) |
| 221 << "Invalid data range"; | 237 << "Invalid data range"; |
| 222 DCHECK_EQ(item.type, DataElement::TYPE_BYTES) << "Invalid element type"; | 238 DCHECK_EQ(item.type, DataElement::TYPE_BYTES) << "Invalid element type"; |
| 223 | 239 |
| 224 switch (request.transport_strategy) { | 240 switch (request.transport_strategy) { |
| 225 case IPCBlobItemRequestStrategy::IPC: { | 241 case IPCBlobItemRequestStrategy::IPC: { |
| 226 responses.push_back(BlobItemBytesResponse(request.request_number)); | 242 responses.push_back(BlobItemBytesResponse(request.request_number)); |
| 227 BlobItemBytesResponse& response = responses.back(); | 243 BlobItemBytesResponse& response = responses.back(); |
| 228 ReadStatus status = consolidation->ReadMemory( | 244 ReadStatus status = consolidation->ReadMemory( |
| 229 request.renderer_item_index, request.renderer_item_offset, | 245 request.renderer_item_index, request.renderer_item_offset, |
| 230 request.size, response.allocate_mutable_data(request.size)); | 246 request.size, response.allocate_mutable_data(request.size)); |
| 231 DCHECK(status == ReadStatus::OK) | 247 DCHECK(status == ReadStatus::OK) |
| 232 << "Error reading from consolidated blob: " | 248 << "Error reading from consolidated blob: " |
| 233 << static_cast<int>(status); | 249 << static_cast<int>(status); |
| 234 break; | 250 break; |
| 235 } | 251 } |
| 236 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { | 252 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { |
| 237 responses.push_back(BlobItemBytesResponse(request.request_number)); | 253 responses.push_back(BlobItemBytesResponse(request.request_number)); |
| 238 DCHECK_LT(request.handle_index, memory_handles->size()) | |
| 239 << "Invalid handle index."; | |
| 240 SharedMemory* memory = opened_memory[request.handle_index]; | 254 SharedMemory* memory = opened_memory[request.handle_index]; |
| 241 if (!memory) { | 255 if (!memory) { |
| 242 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; | 256 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; |
| 257 size_t size = shared_memory_sizes[request.handle_index]; |
| 243 DCHECK(SharedMemory::IsHandleValid(handle)); | 258 DCHECK(SharedMemory::IsHandleValid(handle)); |
| 244 std::unique_ptr<SharedMemory> shared_memory( | 259 std::unique_ptr<SharedMemory> shared_memory( |
| 245 new SharedMemory(handle, false)); | 260 new SharedMemory(handle, false)); |
| 246 | 261 |
| 247 if (!shared_memory->Map(request.size)) { | 262 if (!shared_memory->Map(size)) { |
| 248 // This would happen if the renderer process doesn't have enough | 263 // This would happen if the renderer process doesn't have enough |
| 249 // memory to map the shared memory, which is possible if we don't | 264 // memory to map the shared memory, which is possible if we don't |
| 250 // have much memory. If this scenario happens often, we could delay | 265 // have much memory. If this scenario happens often, we could delay |
| 251 // the response until we have enough memory. For now we just fail. | 266 // the response until we have enough memory. For now we just fail. |
| 252 CHECK(false) << "Unable to map shared memory to send blob " << uuid | 267 CHECK(false) << "Unable to map shared memory to send blob " << uuid |
| 253 << "."; | 268 << "."; |
| 254 return; | 269 return; |
| 255 } | 270 } |
| 256 memory = shared_memory.get(); | 271 memory = shared_memory.get(); |
| 257 opened_memory[request.handle_index] = shared_memory.release(); | 272 opened_memory[request.handle_index] = shared_memory.release(); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 | 412 |
| 398 void BlobTransportController::ReleaseBlobConsolidation( | 413 void BlobTransportController::ReleaseBlobConsolidation( |
| 399 const std::string& uuid) { | 414 const std::string& uuid) { |
| 400 if (blob_storage_.erase(uuid)) { | 415 if (blob_storage_.erase(uuid)) { |
| 401 main_thread_runner_->PostTask(FROM_HERE, | 416 main_thread_runner_->PostTask(FROM_HERE, |
| 402 base::Bind(&DecChildProcessRefCount)); | 417 base::Bind(&DecChildProcessRefCount)); |
| 403 } | 418 } |
| 404 } | 419 } |
| 405 | 420 |
| 406 } // namespace content | 421 } // namespace content |
| OLD | NEW |