| 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> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/files/file.h" | 15 #include "base/files/file.h" |
| 16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 19 #include "base/memory/scoped_vector.h" | |
| 20 #include "base/memory/shared_memory.h" | 19 #include "base/memory/shared_memory.h" |
| 21 #include "base/metrics/histogram_macros.h" | 20 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/numerics/safe_conversions.h" | 21 #include "base/numerics/safe_conversions.h" |
| 23 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
| 24 #include "base/stl_util.h" | 23 #include "base/stl_util.h" |
| 25 #include "base/task_runner.h" | 24 #include "base/task_runner.h" |
| 26 #include "base/task_runner_util.h" | 25 #include "base/task_runner_util.h" |
| 27 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
| 28 #include "base/time/time.h" | 27 #include "base/time/time.h" |
| 29 #include "content/child/blob_storage/blob_consolidation.h" | 28 #include "content/child/blob_storage/blob_consolidation.h" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 return; | 202 return; |
| 204 | 203 |
| 205 BlobConsolidation* consolidation = it->second.get(); | 204 BlobConsolidation* consolidation = it->second.get(); |
| 206 const auto& consolidated_items = consolidation->consolidated_items(); | 205 const auto& consolidated_items = consolidation->consolidated_items(); |
| 207 | 206 |
| 208 std::unique_ptr<std::vector<BlobItemBytesRequest>> file_requests( | 207 std::unique_ptr<std::vector<BlobItemBytesRequest>> file_requests( |
| 209 new std::vector<BlobItemBytesRequest>()); | 208 new std::vector<BlobItemBytesRequest>()); |
| 210 | 209 |
| 211 // 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 |
| 212 // requests, we keep them in a vector and lazily create them. | 211 // requests, we keep them in a vector and lazily create them. |
| 213 ScopedVector<SharedMemory> opened_memory; | 212 std::vector<std::unique_ptr<SharedMemory>> opened_memory( |
| 214 opened_memory.resize(memory_handles->size()); | 213 memory_handles->size()); |
| 215 | 214 |
| 216 // We need to calculate how much memory we expect to be writing to the memory | 215 // We need to calculate how much memory we expect to be writing to the memory |
| 217 // segments so we can correctly map it the first time. | 216 // segments so we can correctly map it the first time. |
| 218 std::vector<size_t> shared_memory_sizes(memory_handles->size()); | 217 std::vector<size_t> shared_memory_sizes(memory_handles->size()); |
| 219 for (const BlobItemBytesRequest& request : requests) { | 218 for (const BlobItemBytesRequest& request : requests) { |
| 220 if (request.transport_strategy != | 219 if (request.transport_strategy != |
| 221 IPCBlobItemRequestStrategy::SHARED_MEMORY) { | 220 IPCBlobItemRequestStrategy::SHARED_MEMORY) { |
| 222 continue; | 221 continue; |
| 223 } | 222 } |
| 224 DCHECK_LT(request.handle_index, memory_handles->size()) | 223 DCHECK_LT(request.handle_index, memory_handles->size()) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 245 ReadStatus status = consolidation->ReadMemory( | 244 ReadStatus status = consolidation->ReadMemory( |
| 246 request.renderer_item_index, request.renderer_item_offset, | 245 request.renderer_item_index, request.renderer_item_offset, |
| 247 request.size, response.allocate_mutable_data(request.size)); | 246 request.size, response.allocate_mutable_data(request.size)); |
| 248 DCHECK(status == ReadStatus::OK) | 247 DCHECK(status == ReadStatus::OK) |
| 249 << "Error reading from consolidated blob: " | 248 << "Error reading from consolidated blob: " |
| 250 << static_cast<int>(status); | 249 << static_cast<int>(status); |
| 251 break; | 250 break; |
| 252 } | 251 } |
| 253 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { | 252 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { |
| 254 responses.push_back(BlobItemBytesResponse(request.request_number)); | 253 responses.push_back(BlobItemBytesResponse(request.request_number)); |
| 255 SharedMemory* memory = opened_memory[request.handle_index]; | 254 if (!opened_memory[request.handle_index]) { |
| 256 if (!memory) { | |
| 257 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; | 255 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; |
| 258 size_t size = shared_memory_sizes[request.handle_index]; | 256 size_t size = shared_memory_sizes[request.handle_index]; |
| 259 DCHECK(SharedMemory::IsHandleValid(handle)); | 257 DCHECK(SharedMemory::IsHandleValid(handle)); |
| 260 std::unique_ptr<SharedMemory> shared_memory( | 258 auto shared_memory = base::MakeUnique<SharedMemory>(handle, false); |
| 261 new SharedMemory(handle, false)); | |
| 262 | 259 |
| 263 if (!shared_memory->Map(size)) { | 260 if (!shared_memory->Map(size)) { |
| 264 // This would happen if the renderer process doesn't have enough | 261 // This would happen if the renderer process doesn't have enough |
| 265 // memory to map the shared memory, which is possible if we don't | 262 // memory to map the shared memory, which is possible if we don't |
| 266 // have much memory. If this scenario happens often, we could delay | 263 // have much memory. If this scenario happens often, we could delay |
| 267 // the response until we have enough memory. For now we just fail. | 264 // the response until we have enough memory. For now we just fail. |
| 268 CHECK(false) << "Unable to map shared memory to send blob " << uuid | 265 CHECK(false) << "Unable to map shared memory to send blob " << uuid |
| 269 << "."; | 266 << "."; |
| 270 return; | 267 return; |
| 271 } | 268 } |
| 272 memory = shared_memory.get(); | 269 opened_memory[request.handle_index] = std::move(shared_memory); |
| 273 opened_memory[request.handle_index] = shared_memory.release(); | |
| 274 } | 270 } |
| 275 CHECK(memory->memory()) << "Couldn't map memory for blob transfer."; | 271 CHECK(opened_memory[request.handle_index]->memory()) |
| 272 << "Couldn't map memory for blob transfer."; |
| 276 ReadStatus status = consolidation->ReadMemory( | 273 ReadStatus status = consolidation->ReadMemory( |
| 277 request.renderer_item_index, request.renderer_item_offset, | 274 request.renderer_item_index, request.renderer_item_offset, |
| 278 request.size, | 275 request.size, |
| 279 static_cast<char*>(memory->memory()) + request.handle_offset); | 276 static_cast<char*>(opened_memory[request.handle_index]->memory()) + |
| 277 request.handle_offset); |
| 280 DCHECK(status == ReadStatus::OK) | 278 DCHECK(status == ReadStatus::OK) |
| 281 << "Error reading from consolidated blob: " | 279 << "Error reading from consolidated blob: " |
| 282 << static_cast<int>(status); | 280 << static_cast<int>(status); |
| 283 break; | 281 break; |
| 284 } | 282 } |
| 285 case IPCBlobItemRequestStrategy::FILE: | 283 case IPCBlobItemRequestStrategy::FILE: |
| 286 DCHECK_LT(request.handle_index, file_handles.size()) | 284 DCHECK_LT(request.handle_index, file_handles.size()) |
| 287 << "Invalid handle index."; | 285 << "Invalid handle index."; |
| 288 file_requests->push_back(request); | 286 file_requests->push_back(request); |
| 289 break; | 287 break; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 | 408 |
| 411 void BlobTransportController::ReleaseBlobConsolidation( | 409 void BlobTransportController::ReleaseBlobConsolidation( |
| 412 const std::string& uuid) { | 410 const std::string& uuid) { |
| 413 if (blob_storage_.erase(uuid)) { | 411 if (blob_storage_.erase(uuid)) { |
| 414 main_thread_runner_->PostTask(FROM_HERE, | 412 main_thread_runner_->PostTask(FROM_HERE, |
| 415 base::Bind(&DecChildProcessRefCount)); | 413 base::Bind(&DecChildProcessRefCount)); |
| 416 } | 414 } |
| 417 } | 415 } |
| 418 | 416 |
| 419 } // namespace content | 417 } // namespace content |
| OLD | NEW |