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 <set> |
12 #include <string> | 13 #include <string> |
13 #include <vector> | 14 #include <vector> |
14 | 15 |
15 #include "base/callback.h" | 16 #include "base/callback.h" |
| 17 #include "base/files/file.h" |
16 #include "base/macros.h" | 18 #include "base/macros.h" |
17 #include "base/memory/ref_counted.h" | 19 #include "base/memory/ref_counted.h" |
18 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
19 #include "base/memory/shared_memory_handle.h" | 21 #include "base/memory/shared_memory_handle.h" |
20 #include "storage/browser/blob/blob_async_transport_strategy.h" | 22 #include "base/memory/weak_ptr.h" |
| 23 #include "storage/browser/blob/blob_async_transport_request_builder.h" |
21 #include "storage/browser/blob/blob_data_builder.h" | 24 #include "storage/browser/blob/blob_data_builder.h" |
| 25 #include "storage/browser/blob/blob_transport_result.h" |
22 #include "storage/browser/storage_browser_export.h" | 26 #include "storage/browser/storage_browser_export.h" |
23 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 27 #include "storage/common/blob_storage/blob_item_bytes_request.h" |
24 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 28 #include "storage/common/blob_storage/blob_item_bytes_response.h" |
25 #include "storage/common/blob_storage/blob_storage_constants.h" | 29 #include "storage/common/blob_storage/blob_storage_constants.h" |
26 #include "storage/common/data_element.h" | 30 #include "storage/common/data_element.h" |
27 | 31 |
28 namespace base { | 32 namespace base { |
29 class SharedMemory; | 33 class SharedMemory; |
30 } | 34 } |
31 | 35 |
32 namespace storage { | 36 namespace storage { |
| 37 class BlobDataHandle; |
| 38 class BlobStorageContext; |
33 | 39 |
34 // This class holds all blobs that are currently being built asynchronously for | 40 // This class |
35 // a child process. It sends memory request, cancel, and done messages through | 41 // * holds all blobs that are currently being built asynchronously for a child |
36 // the given callbacks. | 42 // process, |
37 // This also includes handling 'shortcut' logic, where the host will use the | 43 // * sends memory requests through the given callback in |StartBuildingBlob|, |
38 // initial data in the description instead of requesting for data if we have | 44 // and uses the BlobTransportResult return value to signify other results, |
39 // enough immediate space. | 45 // * includes all logic for deciding which async transport strategy to use, and |
| 46 // * handles all blob construction communication with the BlobStorageContext. |
| 47 // The method |CancelAll| must be called by the consumer, it is not called on |
| 48 // destruction. |
40 class STORAGE_EXPORT BlobAsyncBuilderHost { | 49 class STORAGE_EXPORT BlobAsyncBuilderHost { |
41 public: | 50 public: |
| 51 using RequestMemoryCallback = base::Callback<void( |
| 52 scoped_ptr<std::vector<storage::BlobItemBytesRequest>>, |
| 53 scoped_ptr<std::vector<base::SharedMemoryHandle>>, |
| 54 scoped_ptr<std::vector<base::File>>)>; |
42 BlobAsyncBuilderHost(); | 55 BlobAsyncBuilderHost(); |
43 virtual ~BlobAsyncBuilderHost(); | 56 ~BlobAsyncBuilderHost(); |
| 57 |
| 58 // This registers the given blob internally and adds it to the storage. |
| 59 // Calling this method also guarentees that the referenced blobs are kept |
| 60 // alive for the duration of the construction of this blob. |
| 61 // We return |
| 62 // * BAD_IPC if we already have the blob registered or if we reference ourself |
| 63 // in the referenced_blob_uuids. |
| 64 // * 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 |
| 66 // REFERENCED_BLOB_BROKEN. |
| 67 // * DONE if we successfully registered the blob. |
| 68 BlobTransportResult RegisterBlobUUID( |
| 69 const std::string& uuid, |
| 70 const std::string& content_type, |
| 71 const std::string& content_disposition, |
| 72 const std::set<std::string>& referenced_blob_uuids, |
| 73 BlobStorageContext* context); |
44 | 74 |
45 // This method begins the construction of the blob given the descriptions. | 75 // This method begins the construction of the blob given the descriptions. |
46 // After this method is called, either of the following can happen. | 76 // When we return: |
47 // * The |done| callback is triggered immediately because we can shortcut the | 77 // * DONE: The blob is finished transfering right away, and is now |
48 // construction. | 78 // successfully saved in the context. |
49 // * The |request_memory| callback is called to request memory from the | 79 // * PENDING_RESPONSES: The async builder host is waiting for responses from |
50 // renderer. This class waits for calls to OnMemoryResponses to continue. | 80 // the renderer. It has called |request_memory| for these responses. |
51 // The last argument in the callback corresponds to file handle sizes. | 81 // * CANCEL_*: We have to cancel the blob construction. This function clears |
52 // When all memory is recieved, the |done| callback is triggered. | 82 // the blob's internal state and marks the blob as broken in the context |
53 // * The |cancel| callback is triggered if there is an error at any point. All | 83 // before returning. |
54 // state for the cancelled blob is cleared before |cancel| is called. | 84 // * BAD_IPC: The arguments were invalid/bad. This marks the blob as broken in |
55 // Returns if the arguments are valid and we have a good IPC message. | 85 // the context before returning. |
56 bool StartBuildingBlob( | 86 BlobTransportResult StartBuildingBlob( |
57 const std::string& uuid, | 87 const std::string& uuid, |
58 const std::string& type, | 88 const std::vector<DataElement>& elements, |
59 const std::vector<DataElement>& descriptions, | |
60 size_t memory_available, | 89 size_t memory_available, |
61 const base::Callback< | 90 BlobStorageContext* context, |
62 void(const std::vector<storage::BlobItemBytesRequest>&, | 91 const RequestMemoryCallback& request_memory); |
63 const std::vector<base::SharedMemoryHandle>&, | |
64 const std::vector<uint64_t>&)>& request_memory, | |
65 const base::Callback<void(const BlobDataBuilder&)>& done, | |
66 const base::Callback<void(IPCBlobCreationCancelCode)>& cancel); | |
67 | 92 |
68 // This is called when we have responses from the Renderer to our calls to | 93 // This is called when we have responses from the Renderer to our calls to |
69 // the request_memory callback above. | 94 // the request_memory callback above. See above for return value meaning. |
70 // Returns if the arguments are valid and we have a good IPC message. | 95 BlobTransportResult OnMemoryResponses( |
71 bool OnMemoryResponses(const std::string& uuid, | 96 const std::string& uuid, |
72 const std::vector<BlobItemBytesResponse>& responses); | 97 const std::vector<BlobItemBytesResponse>& responses, |
| 98 BlobStorageContext* context); |
73 | 99 |
74 // This erases the blob building state. | 100 // This removes the BlobBuildingState from our map and flags the blob as |
75 void StopBuildingBlob(const std::string& uuid); | 101 // broken in the context. This can be called both from our own logic to cancel |
| 102 // the blob, or from the DispatcherHost (Renderer). If the blob isn't being |
| 103 // built then we do nothing. |
| 104 // Note: if the blob isn't in the context (renderer dereferenced it before we |
| 105 // finished constructing), then we don't bother touching the context. |
| 106 void CancelBuildingBlob(const std::string& uuid, |
| 107 IPCBlobCreationCancelCode code, |
| 108 BlobStorageContext* context); |
| 109 |
| 110 // This clears this object of pending construction. It also handles marking |
| 111 // blobs that haven't been fully constructed as broken in the context if there |
| 112 // are any references being held by anyone. |
| 113 void CancelAll(BlobStorageContext* context); |
76 | 114 |
77 size_t blob_building_count() const { return async_blob_map_.size(); } | 115 size_t blob_building_count() const { return async_blob_map_.size(); } |
78 | 116 |
| 117 bool IsBeingBuilt(const std::string& key) const { |
| 118 return async_blob_map_.find(key) != async_blob_map_.end(); |
| 119 } |
| 120 |
79 // For testing use only. Must be called before StartBuildingBlob. | 121 // For testing use only. Must be called before StartBuildingBlob. |
80 void SetMemoryConstantsForTesting(size_t max_ipc_memory_size, | 122 void SetMemoryConstantsForTesting(size_t max_ipc_memory_size, |
81 size_t max_shared_memory_size, | 123 size_t max_shared_memory_size, |
82 uint64_t max_file_size) { | 124 uint64_t max_file_size) { |
83 max_ipc_memory_size_ = max_ipc_memory_size; | 125 max_ipc_memory_size_ = max_ipc_memory_size; |
84 max_shared_memory_size_ = max_shared_memory_size; | 126 max_shared_memory_size_ = max_shared_memory_size; |
85 max_file_size_ = max_file_size; | 127 max_file_size_ = max_file_size; |
86 } | 128 } |
87 | 129 |
88 private: | 130 private: |
89 struct BlobBuildingState { | 131 struct BlobBuildingState { |
90 BlobBuildingState(); | 132 // |refernced_blob_handles| should be all handles generated from the set |
| 133 // of |refernced_blob_uuids|. |
| 134 BlobBuildingState( |
| 135 const std::string& uuid, |
| 136 std::set<std::string> referenced_blob_uuids, |
| 137 std::vector<scoped_ptr<BlobDataHandle>>* referenced_blob_handles); |
91 ~BlobBuildingState(); | 138 ~BlobBuildingState(); |
92 | 139 |
93 std::string type; | 140 BlobAsyncTransportRequestBuilder request_builder; |
94 BlobAsyncTransportStrategy transport_strategy; | 141 BlobDataBuilder data_builder; |
95 size_t next_request; | 142 std::vector<bool> request_received; |
96 size_t num_fulfilled_requests; | 143 size_t next_request = 0; |
| 144 size_t num_fulfilled_requests = 0; |
97 scoped_ptr<base::SharedMemory> shared_memory_block; | 145 scoped_ptr<base::SharedMemory> shared_memory_block; |
98 // This is the number of requests that have been sent to populate the above | 146 // This is the number of requests that have been sent to populate the above |
99 // shared data. We won't ask for more data in shared memory until all | 147 // shared data. We won't ask for more data in shared memory until all |
100 // requests have been responded to. | 148 // requests have been responded to. |
101 size_t num_shared_memory_requests; | 149 size_t num_shared_memory_requests = 0; |
102 // Only relevant if num_shared_memory_requests is > 0 | 150 // Only relevant if num_shared_memory_requests is > 0 |
103 size_t current_shared_memory_handle_index; | 151 size_t current_shared_memory_handle_index = 0; |
104 | 152 |
105 base::Callback<void(const std::vector<storage::BlobItemBytesRequest>&, | 153 // We save these to double check that the RegisterBlob and StartBuildingBlob |
106 const std::vector<base::SharedMemoryHandle>&, | 154 // messages are in sync. |
107 const std::vector<uint64_t>&)> request_memory_callback; | 155 std::set<std::string> referenced_blob_uuids; |
108 base::Callback<void(const BlobDataBuilder&)> done_callback; | 156 // These are the blobs that are referenced in the newly constructed blob. |
109 base::Callback<void(IPCBlobCreationCancelCode)> cancel_callback; | 157 // We use these to make sure they stay alive while we create the new blob, |
| 158 // and to wait until any blobs that are not done building are fully |
| 159 // constructed. |
| 160 std::vector<scoped_ptr<BlobDataHandle>> referenced_blob_handles; |
| 161 |
| 162 // These are the number of blobs we're waiting for before we can start |
| 163 // building. |
| 164 size_t num_referenced_blobs_building = 0; |
| 165 |
| 166 BlobAsyncBuilderHost::RequestMemoryCallback request_memory_callback; |
110 }; | 167 }; |
111 | 168 |
112 typedef std::map<std::string, scoped_ptr<BlobBuildingState>> AsyncBlobMap; | 169 typedef std::map<std::string, scoped_ptr<BlobBuildingState>> AsyncBlobMap; |
113 | 170 |
114 // This is the 'main loop' of our memory requests to the renderer. | 171 // This is the 'main loop' of our memory requests to the renderer. |
115 void ContinueBlobMemoryRequests(const std::string& uuid); | 172 BlobTransportResult ContinueBlobMemoryRequests(const std::string& uuid, |
| 173 BlobStorageContext* context); |
116 | 174 |
117 void CancelAndCleanup(const std::string& uuid, | 175 // This is our callback for when we want to finish the blob and we're waiting |
118 IPCBlobCreationCancelCode code); | 176 // for blobs we reference to be built. When the last callback occurs, we |
119 void DoneAndCleanup(const std::string& uuid); | 177 // complete the blob and erase our internal state. |
| 178 void ReferencedBlobFinished(const std::string& uuid, |
| 179 base::WeakPtr<BlobStorageContext> context, |
| 180 bool construction_success); |
| 181 |
| 182 // This finishes creating the blob in the context, decrements blob references |
| 183 // that we were holding during construction, and erases our state. |
| 184 void FinishBuildingBlob(BlobBuildingState* state, |
| 185 BlobStorageContext* context); |
120 | 186 |
121 AsyncBlobMap async_blob_map_; | 187 AsyncBlobMap async_blob_map_; |
122 | 188 |
123 // Here for testing. | 189 // Here for testing. |
124 size_t max_ipc_memory_size_ = kBlobStorageIPCThresholdBytes; | 190 size_t max_ipc_memory_size_ = kBlobStorageIPCThresholdBytes; |
125 size_t max_shared_memory_size_ = kBlobStorageMaxSharedMemoryBytes; | 191 size_t max_shared_memory_size_ = kBlobStorageMaxSharedMemoryBytes; |
126 uint64_t max_file_size_ = kBlobStorageMaxFileSizeBytes; | 192 uint64_t max_file_size_ = kBlobStorageMaxFileSizeBytes; |
127 | 193 |
| 194 base::WeakPtrFactory<BlobAsyncBuilderHost> ptr_factory_; |
| 195 |
128 DISALLOW_COPY_AND_ASSIGN(BlobAsyncBuilderHost); | 196 DISALLOW_COPY_AND_ASSIGN(BlobAsyncBuilderHost); |
129 }; | 197 }; |
130 | 198 |
131 } // namespace storage | 199 } // namespace storage |
132 #endif // STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ | 200 #endif // STORAGE_BROWSER_BLOB_BLOB_ASYNC_BUILDER_HOST_H_ |
OLD | NEW |