| 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 #ifndef STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ |    5 #ifndef STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ | 
|    6 #define STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ |    6 #define STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ | 
|    7  |    7  | 
|    8 #include <stddef.h> |    8 #include <stddef.h> | 
|    9 #include <stdint.h> |    9 #include <stdint.h> | 
|   10  |   10  | 
|   11 #include <map> |   11 #include <map> | 
|   12 #include <memory> |   12 #include <memory> | 
|   13 #include <set> |   13 #include <set> | 
|   14 #include <string> |   14 #include <string> | 
|   15 #include <vector> |   15 #include <vector> | 
|   16  |   16  | 
|   17 #include "base/callback.h" |   17 #include "base/callback.h" | 
|   18 #include "base/files/file.h" |   18 #include "base/files/file.h" | 
|   19 #include "base/macros.h" |   19 #include "base/macros.h" | 
|   20 #include "base/memory/ref_counted.h" |   20 #include "base/memory/ref_counted.h" | 
|   21 #include "base/memory/shared_memory_handle.h" |   21 #include "base/memory/shared_memory_handle.h" | 
|   22 #include "base/memory/weak_ptr.h" |   22 #include "base/memory/weak_ptr.h" | 
|   23 #include "storage/browser/blob/blob_async_transport_request_builder.h" |   23 #include "storage/browser/blob/blob_async_transport_request_builder.h" | 
|   24 #include "storage/browser/blob/blob_data_builder.h" |   24 #include "storage/browser/blob/blob_data_builder.h" | 
 |   25 #include "storage/browser/blob/blob_memory_controller.h" | 
|   25 #include "storage/browser/blob/blob_transport_result.h" |   26 #include "storage/browser/blob/blob_transport_result.h" | 
|   26 #include "storage/browser/storage_browser_export.h" |   27 #include "storage/browser/storage_browser_export.h" | 
|   27 #include "storage/common/blob_storage/blob_item_bytes_request.h" |   28 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 
|   28 #include "storage/common/blob_storage/blob_item_bytes_response.h" |   29 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 
|   29 #include "storage/common/blob_storage/blob_storage_constants.h" |   30 #include "storage/common/blob_storage/blob_storage_constants.h" | 
|   30 #include "storage/common/data_element.h" |   31 #include "storage/common/data_element.h" | 
|   31  |   32  | 
|   32 namespace base { |   33 namespace base { | 
|   33 class SharedMemory; |   34 class SharedMemory; | 
|   34 } |   35 } | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   45 // * includes all logic for deciding which async transport strategy to use, and |   46 // * includes all logic for deciding which async transport strategy to use, and | 
|   46 // * handles all blob construction communication with the BlobStorageContext. |   47 // * handles all blob construction communication with the BlobStorageContext. | 
|   47 // The method |CancelAll| must be called by the consumer, it is not called on |   48 // The method |CancelAll| must be called by the consumer, it is not called on | 
|   48 // destruction. |   49 // destruction. | 
|   49 class STORAGE_EXPORT BlobAsyncBuilderHost { |   50 class STORAGE_EXPORT BlobAsyncBuilderHost { | 
|   50  public: |   51  public: | 
|   51   using RequestMemoryCallback = base::Callback<void( |   52   using RequestMemoryCallback = base::Callback<void( | 
|   52       std::unique_ptr<std::vector<storage::BlobItemBytesRequest>>, |   53       std::unique_ptr<std::vector<storage::BlobItemBytesRequest>>, | 
|   53       std::unique_ptr<std::vector<base::SharedMemoryHandle>>, |   54       std::unique_ptr<std::vector<base::SharedMemoryHandle>>, | 
|   54       std::unique_ptr<std::vector<base::File>>)>; |   55       std::unique_ptr<std::vector<base::File>>)>; | 
 |   56   using ErrorCallback = base::Callback<void(IPCBlobCreationCancelCode)>; | 
 |   57   using DoneCallback = base::Closure; | 
 |   58  | 
|   55   BlobAsyncBuilderHost(); |   59   BlobAsyncBuilderHost(); | 
|   56   ~BlobAsyncBuilderHost(); |   60   ~BlobAsyncBuilderHost(); | 
|   57  |   61  | 
|   58   // This registers the given blob internally and adds it to the storage. |   62   // This registers the given blob internally and adds it to the storage. | 
|   59   // Calling this method also guarentees that the referenced blobs are kept |   63   // Calling this method also guarentees that the referenced blobs are kept | 
|   60   // alive for the duration of the construction of this blob. |   64   // alive for the duration of the construction of this blob. | 
|   61   // We return |   65   // We return | 
|   62   // * BAD_IPC if we already have the blob registered or if we reference ourself |   66   // * BAD_IPC if we already have the blob registered or if we reference ourself | 
|   63   //   in the referenced_blob_uuids. |   67   //   in the referenced_blob_uuids. | 
|   64   // * CANCEL_REFERENCED_BLOB_BROKEN if one of the referenced blobs is broken or |   68   // * CANCEL_REFERENCED_BLOB_BROKEN if one of the referenced blobs is broken or | 
|   65   //   doesn't exist. We store the blob in the context as broken  with code |   69   //   doesn't exist. We store the blob in the context as broken  with code | 
|   66   //   REFERENCED_BLOB_BROKEN. |   70   //   REFERENCED_BLOB_BROKEN. | 
|   67   // * DONE if we successfully registered the blob. |   71   // * DONE if we successfully registered the blob. | 
|   68   BlobTransportResult RegisterBlobUUID( |   72   BlobTransportResult RegisterBlob( | 
|   69       const std::string& uuid, |   73       const std::string& uuid, | 
|   70       const std::string& content_type, |   74       const std::string& content_type, | 
|   71       const std::string& content_disposition, |   75       const std::string& content_disposition, | 
|   72       const std::set<std::string>& referenced_blob_uuids, |   76       const std::vector<DataElement>& elements, | 
|   73       BlobStorageContext* context); |   77       BlobStorageContext* context, | 
 |   78       std::unique_ptr<BlobDataHandle>* handle_output, | 
 |   79       const RequestMemoryCallback& request_memory, | 
 |   80       const ErrorCallback& report_error, | 
 |   81       const DoneCallback& done_callback); | 
|   74  |   82  | 
|   75   // This method begins the construction of the blob given the descriptions. The |   83   // This method begins the construction of the blob given the descriptions. The | 
|   76   // blob uuid MUST be building in this object. |   84   // blob uuid MUST be building in this object. | 
|   77   // When we return: |   85   // When we return: | 
|   78   // * DONE: The blob is finished transfering right away, and is now |   86   // * DONE: The blob is finished transfering right away, and is now | 
|   79   //   successfully saved in the context. |   87   //   successfully saved in the context. | 
|   80   // * PENDING_RESPONSES: The async builder host is waiting for responses from |   88   // * PENDING_RESPONSES: The async builder host is waiting for responses from | 
|   81   //   the renderer. It has called |request_memory| for these responses. |   89   //   the renderer. It has called |request_memory| for these responses. | 
|   82   // * CANCEL_*: We have to cancel the blob construction. This function clears |   90   // * CANCEL_*: We have to cancel the blob construction. This function clears | 
|   83   //   the blob's internal state and marks the blob as broken in the context |   91   //   the blob's internal state and marks the blob as broken in the context | 
|   84   //   before returning. |   92   //   before returning. | 
|   85   // * BAD_IPC: The arguments were invalid/bad. This marks the blob as broken in |   93   // * BAD_IPC: The arguments were invalid/bad. This marks the blob as broken in | 
|   86   //   the context before returning. |   94   //   the context before returning. | 
|   87   BlobTransportResult StartBuildingBlob( |  | 
|   88       const std::string& uuid, |  | 
|   89       const std::vector<DataElement>& elements, |  | 
|   90       size_t memory_available, |  | 
|   91       BlobStorageContext* context, |  | 
|   92       const RequestMemoryCallback& request_memory); |  | 
|   93  |   95  | 
|   94   // This is called when we have responses from the Renderer to our calls to |   96   // This is called when we have responses from the Renderer to our calls to | 
|   95   // the request_memory callback above. See above for return value meaning. |   97   // the request_memory callback above. See above for return value meaning. | 
|   96   BlobTransportResult OnMemoryResponses( |   98   BlobTransportResult OnMemoryResponses( | 
|   97       const std::string& uuid, |   99       const std::string& uuid, | 
|   98       const std::vector<BlobItemBytesResponse>& responses, |  100       const std::vector<BlobItemBytesResponse>& responses, | 
|   99       BlobStorageContext* context); |  101       BlobStorageContext* context); | 
|  100  |  102  | 
|  101   // This removes the BlobBuildingState from our map and flags the blob as |  103   // This removes the BlobBuildingState from our map and flags the blob as | 
|  102   // broken in the context. This can be called both from our own logic to cancel |  104   // broken in the context. This can be called both from our own logic to cancel | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  115   void CancelAll(BlobStorageContext* context); |  117   void CancelAll(BlobStorageContext* context); | 
|  116  |  118  | 
|  117   bool IsEmpty() const { return async_blob_map_.empty(); } |  119   bool IsEmpty() const { return async_blob_map_.empty(); } | 
|  118  |  120  | 
|  119   size_t blob_building_count() const { return async_blob_map_.size(); } |  121   size_t blob_building_count() const { return async_blob_map_.size(); } | 
|  120  |  122  | 
|  121   bool IsBeingBuilt(const std::string& key) const { |  123   bool IsBeingBuilt(const std::string& key) const { | 
|  122     return async_blob_map_.find(key) != async_blob_map_.end(); |  124     return async_blob_map_.find(key) != async_blob_map_.end(); | 
|  123   } |  125   } | 
|  124  |  126  | 
|  125   // For testing use only.  Must be called before StartBuildingBlob. |  | 
|  126   void SetMemoryConstantsForTesting(size_t max_ipc_memory_size, |  | 
|  127                                     size_t max_shared_memory_size, |  | 
|  128                                     uint64_t max_file_size) { |  | 
|  129     max_ipc_memory_size_ = max_ipc_memory_size; |  | 
|  130     max_shared_memory_size_ = max_shared_memory_size; |  | 
|  131     max_file_size_ = max_file_size; |  | 
|  132   } |  | 
|  133  |  | 
|  134  private: |  127  private: | 
|  135   struct BlobBuildingState { |  128   struct BlobBuildingState { | 
|  136     // |refernced_blob_handles| should be all handles generated from the set |  129     // |refernced_blob_handles| should be all handles generated from the set | 
|  137     // of |refernced_blob_uuids|. |  130     // of |refernced_blob_uuids|. | 
|  138     BlobBuildingState( |  131     BlobBuildingState(const std::string& uuid); | 
|  139         const std::string& uuid, |  | 
|  140         std::set<std::string> referenced_blob_uuids, |  | 
|  141         std::vector<std::unique_ptr<BlobDataHandle>>* referenced_blob_handles); |  | 
|  142     ~BlobBuildingState(); |  132     ~BlobBuildingState(); | 
|  143  |  133  | 
 |  134     IPCBlobItemRequestStrategy strategy = IPCBlobItemRequestStrategy::UNKNOWN; | 
|  144     BlobAsyncTransportRequestBuilder request_builder; |  135     BlobAsyncTransportRequestBuilder request_builder; | 
|  145     BlobDataBuilder data_builder; |  136     BlobDataBuilder data_builder; | 
|  146     std::vector<bool> request_received; |  137     std::vector<bool> request_received; | 
 |  138     size_t num_fulfilled_requests = 0; | 
 |  139  | 
 |  140     bool waiting_until_room_for_transport = false; | 
 |  141     BlobMemoryController::PendingContructionEntry pending_entry; | 
 |  142     RequestMemoryCallback request_memory_callback; | 
 |  143     ErrorCallback error_callback; | 
 |  144     DoneCallback done_callback; | 
 |  145  | 
 |  146     // Used by shared memory strategy. | 
|  147     size_t next_request = 0; |  147     size_t next_request = 0; | 
|  148     size_t num_fulfilled_requests = 0; |  | 
|  149     std::unique_ptr<base::SharedMemory> shared_memory_block; |  148     std::unique_ptr<base::SharedMemory> shared_memory_block; | 
|  150     // This is the number of requests that have been sent to populate the above |  149     // This is the number of requests that have been sent to populate the above | 
|  151     // shared data. We won't ask for more data in shared memory until all |  150     // shared data. We won't ask for more data in shared memory until all | 
|  152     // requests have been responded to. |  151     // requests have been responded to. | 
|  153     size_t num_shared_memory_requests = 0; |  152     size_t num_shared_memory_requests = 0; | 
|  154     // Only relevant if num_shared_memory_requests is > 0 |  153     // Only relevant if num_shared_memory_requests is > 0 | 
|  155     size_t current_shared_memory_handle_index = 0; |  154     size_t current_shared_memory_handle_index = 0; | 
|  156  |  155  | 
|  157     // We save these to double check that the RegisterBlob and StartBuildingBlob |  156     // Used by file strategy. | 
|  158     // messages are in sync. |  157     std::vector<scoped_refptr<ShareableFileReference>> files; | 
|  159     std::set<std::string> referenced_blob_uuids; |  | 
|  160     // These are the blobs that are referenced in the newly constructed blob. |  | 
|  161     // We use these to make sure they stay alive while we create the new blob, |  | 
|  162     // and to wait until any blobs that are not done building are fully |  | 
|  163     // constructed. |  | 
|  164     std::vector<std::unique_ptr<BlobDataHandle>> referenced_blob_handles; |  | 
|  165  |  | 
|  166     // These are the number of blobs we're waiting for before we can start |  | 
|  167     // building. |  | 
|  168     size_t num_referenced_blobs_building = 0; |  | 
|  169  |  | 
|  170     BlobAsyncBuilderHost::RequestMemoryCallback request_memory_callback; |  | 
|  171   }; |  158   }; | 
|  172  |  159  | 
|  173   typedef std::map<std::string, std::unique_ptr<BlobBuildingState>> |  160   typedef std::map<std::string, std::unique_ptr<BlobBuildingState>> | 
|  174       AsyncBlobMap; |  161       AsyncBlobMap; | 
|  175  |  162  | 
 |  163   BlobTransportResult StartRequests(const std::string& uuid, | 
 |  164                                     BlobBuildingState* state, | 
 |  165                                     BlobStorageContext* context); | 
 |  166  | 
 |  167   void OnCanStartBuildingBlob(const std::string& uuid, | 
 |  168                               base::WeakPtr<BlobStorageContext> context, | 
 |  169                               bool success); | 
 |  170  | 
 |  171   void SendIPCRequests(BlobBuildingState* state, BlobStorageContext* context); | 
 |  172   BlobTransportResult OnIPCResponses( | 
 |  173       const std::string& uuid, | 
 |  174       BlobBuildingState* state, | 
 |  175       const std::vector<BlobItemBytesResponse>& responses, | 
 |  176       BlobStorageContext* context); | 
 |  177  | 
|  176   // This is the 'main loop' of our memory requests to the renderer. |  178   // This is the 'main loop' of our memory requests to the renderer. | 
|  177   BlobTransportResult ContinueBlobMemoryRequests(const std::string& uuid, |  179   BlobTransportResult ContinueSharedMemoryRequests(const std::string& uuid, | 
|  178                                                  BlobStorageContext* context); |  180                                                    BlobBuildingState* state, | 
 |  181                                                    BlobStorageContext* context); | 
|  179  |  182  | 
|  180   // This is our callback for when we want to finish the blob and we're waiting |  183   BlobTransportResult OnSharedMemoryResponses( | 
|  181   // for blobs we reference to be built. When the last callback occurs, we |  184       const std::string& uuid, | 
|  182   // complete the blob and erase our internal state. |  185       BlobBuildingState* state, | 
|  183   void ReferencedBlobFinished(const std::string& uuid, |  186       const std::vector<BlobItemBytesResponse>& responses, | 
|  184                               base::WeakPtr<BlobStorageContext> context, |  187       BlobStorageContext* context); | 
|  185                               bool construction_success, |  188  | 
|  186                               IPCBlobCreationCancelCode reason); |  189   void OnFileCreated(const std::string& uuid, | 
 |  190                      size_t handle_index, | 
 |  191                      BlobMemoryController::FileCreationInfo file_info); | 
 |  192  | 
 |  193   BlobTransportResult OnFileResponses( | 
 |  194       const std::string& uuid, | 
 |  195       BlobBuildingState* state, | 
 |  196       const std::vector<BlobItemBytesResponse>& responses, | 
 |  197       BlobStorageContext* context); | 
|  187  |  198  | 
|  188   // This finishes creating the blob in the context, decrements blob references |  199   // This finishes creating the blob in the context, decrements blob references | 
|  189   // that we were holding during construction, and erases our state. |  200   // that we were holding during construction, and erases our state. | 
|  190   void FinishBuildingBlob(BlobBuildingState* state, |  201   void FinishBuildingBlob(BlobBuildingState* state, | 
|  191                           BlobStorageContext* context); |  202                           BlobStorageContext* context); | 
|  192  |  203  | 
|  193   AsyncBlobMap async_blob_map_; |  204   AsyncBlobMap async_blob_map_; | 
|  194  |  | 
|  195   // Here for testing. |  | 
|  196   size_t max_ipc_memory_size_ = kBlobStorageIPCThresholdBytes; |  | 
|  197   size_t max_shared_memory_size_ = kBlobStorageMaxSharedMemoryBytes; |  | 
|  198   uint64_t max_file_size_ = kBlobStorageMaxFileSizeBytes; |  | 
|  199  |  | 
|  200   base::WeakPtrFactory<BlobAsyncBuilderHost> ptr_factory_; |  205   base::WeakPtrFactory<BlobAsyncBuilderHost> ptr_factory_; | 
|  201  |  206  | 
|  202   DISALLOW_COPY_AND_ASSIGN(BlobAsyncBuilderHost); |  207   DISALLOW_COPY_AND_ASSIGN(BlobAsyncBuilderHost); | 
|  203 }; |  208 }; | 
|  204  |  209  | 
|  205 }  // namespace storage |  210 }  // namespace storage | 
|  206 #endif  // STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ |  211 #endif  // STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ | 
| OLD | NEW |