Index: content/child/blob_storage/blob_transport_controller.cc |
diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc |
index c2b639ad921d66879b031117191d1fa01bad0db0..3c8373ec94342e48fe3b6cfa221d0cb49c4e828f 100644 |
--- a/content/child/blob_storage/blob_transport_controller.cc |
+++ b/content/child/blob_storage/blob_transport_controller.cc |
@@ -27,6 +27,7 @@ using storage::BlobItemBytesRequest; |
using storage::BlobItemBytesResponse; |
using storage::IPCBlobItemRequestStrategy; |
using storage::DataElement; |
+using storage::kBlobStorageIPCThresholdBytes; |
namespace content { |
@@ -36,8 +37,7 @@ using ConsolidatedItem = BlobConsolidation::ConsolidatedItem; |
using ReadStatus = BlobConsolidation::ReadStatus; |
namespace { |
-const size_t kLargeThresholdBytes = 250 * 1024; |
-static base::LazyInstance<BlobTransportController> g_controller = |
+static base::LazyInstance<BlobTransportController>::Leaky g_controller = |
LAZY_INSTANCE_INITIALIZER; |
// This keeps the process alive while blobs are being transferred. |
@@ -54,23 +54,40 @@ BlobTransportController* BlobTransportController::GetInstance() { |
return g_controller.Pointer(); |
} |
-BlobTransportController::~BlobTransportController() {} |
- |
+// static |
void BlobTransportController::InitiateBlobTransfer( |
const std::string& uuid, |
scoped_ptr<BlobConsolidation> consolidation, |
- IPC::Sender* sender, |
+ scoped_refptr<ThreadSafeSender> sender, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& io_runner, |
scoped_refptr<base::SingleThreadTaskRunner> main_runner) { |
+ if (main_runner->BelongsToCurrentThread()) { |
+ IncChildProcessRefCount(); |
michaeln
2016/04/05 00:18:04
having to do this immediately makes sense
|
+ } else { |
+ main_runner->PostTask(FROM_HERE, base::Bind(&IncChildProcessRefCount)); |
+ } |
+ |
+ // If we fit in IPC, then shortcut our process by sending the descriptions |
+ // right away. We schedule our task on the IO thread first as an extra |
+ // precaution that we will store the consolidation object before we get any |
+ // response from the browser. |
BlobConsolidation* consolidation_ptr = consolidation.get(); |
- if (blob_storage_.empty()) { |
- main_thread_runner_ = std::move(main_runner); |
- main_thread_runner_->PostTask(FROM_HERE, |
- base::Bind(&IncChildProcessRefCount)); |
+ IPC::Sender* sender_ptr = sender.get(); |
+ bool presend_descriptions = |
+ consolidation->total_memory() <= kBlobStorageIPCThresholdBytes; |
+ io_runner->PostTask( |
+ FROM_HERE, |
+ base::Bind(&BlobTransportController::InitiateBlobTransferOnIOThread, |
+ base::Unretained(BlobTransportController::GetInstance()), uuid, |
+ base::Passed(std::move(consolidation)), |
+ base::Passed(std::move(sender)), presend_descriptions, |
+ base::Passed(std::move(main_runner)))); |
+ if (presend_descriptions) { |
michaeln
2016/04/05 00:18:04
Are you sure the presending is necessary? If it's
dmurph
2016/04/05 00:32:04
I don't know if it does, but I strongly suspect th
|
+ std::vector<storage::DataElement> descriptions; |
+ BlobTransportController::GetDescriptions( |
+ consolidation_ptr, kBlobStorageIPCThresholdBytes, &descriptions); |
+ sender_ptr->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions)); |
} |
- blob_storage_[uuid] = std::move(consolidation); |
- std::vector<storage::DataElement> descriptions; |
- GetDescriptions(consolidation_ptr, kLargeThresholdBytes, &descriptions); |
- sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions)); |
} |
void BlobTransportController::OnMemoryRequest( |
@@ -115,16 +132,7 @@ void BlobTransportController::OnDone(const std::string& uuid) { |
ReleaseBlobConsolidation(uuid); |
} |
-void BlobTransportController::ClearForTesting() { |
- if (!blob_storage_.empty() && main_thread_runner_) { |
- main_thread_runner_->PostTask(FROM_HERE, |
- base::Bind(&DecChildProcessRefCount)); |
- } |
- blob_storage_.clear(); |
-} |
- |
-BlobTransportController::BlobTransportController() {} |
- |
+// static |
void BlobTransportController::GetDescriptions( |
BlobConsolidation* consolidation, |
size_t max_data_population, |
@@ -178,6 +186,37 @@ void BlobTransportController::GetDescriptions( |
} |
} |
+BlobTransportController::BlobTransportController() {} |
+ |
+BlobTransportController::~BlobTransportController() {} |
+ |
+void BlobTransportController::ClearForTesting() { |
+ if (!blob_storage_.empty() && main_thread_runner_) { |
+ main_thread_runner_->PostTask(FROM_HERE, |
+ base::Bind(&DecChildProcessRefCount)); |
+ } |
+ blob_storage_.clear(); |
+} |
+ |
+void BlobTransportController::InitiateBlobTransferOnIOThread( |
+ const std::string& uuid, |
+ scoped_ptr<BlobConsolidation> consolidation, |
+ scoped_refptr<ThreadSafeSender> sender, |
+ bool sent_descriptions, |
+ scoped_refptr<base::SingleThreadTaskRunner> main_runner) { |
+ if (!main_thread_runner_.get()) { |
+ main_thread_runner_ = std::move(main_runner); |
+ } |
+ BlobConsolidation* consolidation_ptr = consolidation.get(); |
+ blob_storage_[uuid] = std::move(consolidation); |
+ if (!sent_descriptions) { |
+ std::vector<storage::DataElement> descriptions; |
+ GetDescriptions(consolidation_ptr, kBlobStorageIPCThresholdBytes, |
+ &descriptions); |
+ sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions)); |
+ } |
+} |
+ |
BlobTransportController::ResponsesStatus BlobTransportController::GetResponses( |
const std::string& uuid, |
const std::vector<BlobItemBytesRequest>& requests, |
@@ -255,12 +294,9 @@ BlobTransportController::ResponsesStatus BlobTransportController::GetResponses( |
void BlobTransportController::ReleaseBlobConsolidation( |
const std::string& uuid) { |
- // If we erased something and we're now empty, release the child process |
- // ref count and deref the main thread runner. |
- if (blob_storage_.erase(uuid) && blob_storage_.empty()) { |
+ if (blob_storage_.erase(uuid)) { |
main_thread_runner_->PostTask(FROM_HERE, |
base::Bind(&DecChildProcessRefCount)); |
- main_thread_runner_ = nullptr; |
} |
} |