Chromium Code Reviews| 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; | |
|
Marijn Kruisselbrink
2016/06/21 16:52:35
nit: Why not just pass memory_handles->size() dire
dmurph
2016/06/21 17:33:03
Ah, right, thanks.
| |
| 218 shared_memory_sizes.resize(memory_handles->size(), 0); | |
| 219 for (const BlobItemBytesRequest& request : requests) { | |
| 220 if (request.transport_strategy != | |
| 221 IPCBlobItemRequestStrategy::SHARED_MEMORY) { | |
| 222 continue; | |
| 223 } | |
| 224 shared_memory_sizes[request.handle_index] = | |
| 225 std::max(shared_memory_sizes[request.handle_index], | |
| 226 static_cast<size_t>(request.size + request.handle_offset)); | |
|
Marijn Kruisselbrink
2016/06/21 16:52:35
rather than the static_cast<size_t> you could also
dmurph
2016/06/21 17:33:03
Done.
| |
| 227 } | |
| 228 | |
| 214 for (const BlobItemBytesRequest& request : requests) { | 229 for (const BlobItemBytesRequest& request : requests) { |
| 215 DCHECK_LT(request.renderer_item_index, consolidated_items.size()) | 230 DCHECK_LT(request.renderer_item_index, consolidated_items.size()) |
| 216 << "Invalid item index"; | 231 << "Invalid item index"; |
| 217 | 232 |
| 218 const ConsolidatedItem& item = | 233 const ConsolidatedItem& item = |
| 219 consolidated_items[request.renderer_item_index]; | 234 consolidated_items[request.renderer_item_index]; |
| 220 DCHECK_LE(request.renderer_item_offset + request.size, item.length) | 235 DCHECK_LE(request.renderer_item_offset + request.size, item.length) |
| 221 << "Invalid data range"; | 236 << "Invalid data range"; |
| 222 DCHECK_EQ(item.type, DataElement::TYPE_BYTES) << "Invalid element type"; | 237 DCHECK_EQ(item.type, DataElement::TYPE_BYTES) << "Invalid element type"; |
| 223 | 238 |
| 224 switch (request.transport_strategy) { | 239 switch (request.transport_strategy) { |
| 225 case IPCBlobItemRequestStrategy::IPC: { | 240 case IPCBlobItemRequestStrategy::IPC: { |
| 226 responses.push_back(BlobItemBytesResponse(request.request_number)); | 241 responses.push_back(BlobItemBytesResponse(request.request_number)); |
| 227 BlobItemBytesResponse& response = responses.back(); | 242 BlobItemBytesResponse& response = responses.back(); |
| 228 ReadStatus status = consolidation->ReadMemory( | 243 ReadStatus status = consolidation->ReadMemory( |
| 229 request.renderer_item_index, request.renderer_item_offset, | 244 request.renderer_item_index, request.renderer_item_offset, |
| 230 request.size, response.allocate_mutable_data(request.size)); | 245 request.size, response.allocate_mutable_data(request.size)); |
| 231 DCHECK(status == ReadStatus::OK) | 246 DCHECK(status == ReadStatus::OK) |
| 232 << "Error reading from consolidated blob: " | 247 << "Error reading from consolidated blob: " |
| 233 << static_cast<int>(status); | 248 << static_cast<int>(status); |
| 234 break; | 249 break; |
| 235 } | 250 } |
| 236 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { | 251 case IPCBlobItemRequestStrategy::SHARED_MEMORY: { |
| 237 responses.push_back(BlobItemBytesResponse(request.request_number)); | 252 responses.push_back(BlobItemBytesResponse(request.request_number)); |
| 238 DCHECK_LT(request.handle_index, memory_handles->size()) | 253 DCHECK_LT(request.handle_index, memory_handles->size()) |
|
Marijn Kruisselbrink
2016/06/21 16:52:35
Should you move/copy this DCHECK to your new loop?
dmurph
2016/06/21 17:33:03
Done.
| |
| 239 << "Invalid handle index."; | 254 << "Invalid handle index."; |
| 240 SharedMemory* memory = opened_memory[request.handle_index]; | 255 SharedMemory* memory = opened_memory[request.handle_index]; |
| 241 if (!memory) { | 256 if (!memory) { |
| 242 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; | 257 SharedMemoryHandle& handle = (*memory_handles)[request.handle_index]; |
| 258 size_t size = shared_memory_sizes[request.handle_index]; | |
| 243 DCHECK(SharedMemory::IsHandleValid(handle)); | 259 DCHECK(SharedMemory::IsHandleValid(handle)); |
| 244 std::unique_ptr<SharedMemory> shared_memory( | 260 std::unique_ptr<SharedMemory> shared_memory( |
| 245 new SharedMemory(handle, false)); | 261 new SharedMemory(handle, false)); |
| 246 | 262 |
| 247 if (!shared_memory->Map(request.size)) { | 263 if (!shared_memory->Map(size)) { |
| 248 // This would happen if the renderer process doesn't have enough | 264 // 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 | 265 // 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 | 266 // have much memory. If this scenario happens often, we could delay |
| 251 // the response until we have enough memory. For now we just fail. | 267 // the response until we have enough memory. For now we just fail. |
| 252 CHECK(false) << "Unable to map shared memory to send blob " << uuid | 268 CHECK(false) << "Unable to map shared memory to send blob " << uuid |
| 253 << "."; | 269 << "."; |
| 254 return; | 270 return; |
| 255 } | 271 } |
| 256 memory = shared_memory.get(); | 272 memory = shared_memory.get(); |
| 257 opened_memory[request.handle_index] = shared_memory.release(); | 273 opened_memory[request.handle_index] = shared_memory.release(); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 | 413 |
| 398 void BlobTransportController::ReleaseBlobConsolidation( | 414 void BlobTransportController::ReleaseBlobConsolidation( |
| 399 const std::string& uuid) { | 415 const std::string& uuid) { |
| 400 if (blob_storage_.erase(uuid)) { | 416 if (blob_storage_.erase(uuid)) { |
| 401 main_thread_runner_->PostTask(FROM_HERE, | 417 main_thread_runner_->PostTask(FROM_HERE, |
| 402 base::Bind(&DecChildProcessRefCount)); | 418 base::Bind(&DecChildProcessRefCount)); |
| 403 } | 419 } |
| 404 } | 420 } |
| 405 | 421 |
| 406 } // namespace content | 422 } // namespace content |
| OLD | NEW |