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 |