Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(739)

Side by Side Diff: net/http/http_cache_shared_writers.h

Issue 2519473002: Fixes the cache lock issue. (Closed)
Patch Set: Redesigned the fix using DataAccess class for eliminating Orphan API.(Rebased till refs/heads/master@{#442607}) Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
6 #define NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
7
8 #include <list>
9 #include <memory>
10 #include "base/memory/weak_ptr.h"
11 #include "net/base/completion_callback.h"
12 #include "net/http/http_cache.h"
13
14 namespace net {
15
16 class DataAccess;
17
18 // SharedWriters represents the set of all HttpCache::Transactions that are
19 // reading from the network using the same network transaction and writing to
20 // the same cache entry. It is owned by the ActiveEntry.
21 //
22 // An instance of SharedWriters will be created when the first writer has
23 // written the new response headers in the cache.
24 // At creation:
25 // - The writer’s network transaction’s ownership will be transferred to the new
26 // DataAccess object owned by SharedWriters and thus can be used by any of the
27 // HttpCache::Transactions for subsequent reading from the network.
28 // - The pending_queue will be traversed to see if there are other
29 // transactions that can be added to SharedWriters.
30 //
31 // Destroyed when any of the following happen:
32 // - All the data has been read from the network and written to cache.
33 // - ActiveEntry is destroyed.
34 // - Last transaction part of SharedWriters is destroyed.
35 // - Response writing is terminated due to a failure.
36 // - StopCaching API is invoked and caching was successfully stopped.
Randy Smith (Not in Mondays) 2017/01/19 00:53:43 Suggestion: My model for class documentation is th
shivanisha 2017/01/25 19:46:13 Agree, thanks. Updated the comments in this file t
37 class HttpCache::SharedWriters {
38 public:
39 // Creates a new SharedWriters object, transfers the ownership of network
40 // transaction to SharedWriters, and adds the cache transaction to
41 // all_writers_.
42 SharedWriters(HttpCache* cache,
43 ActiveEntry* entry,
44 Transaction* cache_transaction,
45 RequestPriority priority,
46 std::unique_ptr<HttpTransaction> network_transaction);
Randy Smith (Not in Mondays) 2017/01/19 00:53:43 Recommend documenting lifetimes for raw pointers (
shivanisha 2017/01/25 19:46:13 done.
47 ~SharedWriters();
48
49 // Adds a transaction to SharedWriters. Invokes SetShared on the transaction
50 // and either assigns the transaction to validating_transaction_ or inserts it
51 // in waiting_for_validation_. Return value is true if it is the current
52 // validating_transaction_ and false if its waiting.
53 bool AddTransaction(Transaction* transaction);
54
55 // Invokes Read on data_access_, assigns this transaction to
56 // current_writer_ and returns what data_access_->Read() returns.
57 // In case a read is already in progress then this transaction is instead
58 // added to waiting_writers_, read_in_progress is set to true and
59 // ERR_IO_PENDING is returned.
60 int Read(scoped_refptr<IOBuffer> buf,
61 int buf_len,
62 const CompletionCallback& callback,
63 Transaction* transaction,
64 bool* read_in_progress);
65
66 // Invokes CacheWrite on data_access_ and returns the return value returned
67 // from it. Current_writer_ should be equal to transaction.
68 int CacheWrite(scoped_refptr<IOBuffer> buf,
69 int write_len,
70 const CompletionCallback& callback,
71 Transaction* transaction);
72
73 // Callback to be invoked when validating_transaction_ wants to continue with
74 // the entry as the validation successfully matched it.
75 void OnValidationMatch(Transaction* transaction, RequestPriority priority);
76
77 // Callback to be invoked when validating_transaction_ cannot continue with
78 // the entry as the validation did not return a 304.
79 // Its ok to continue writing to cache if this is the only transaction in
80 // SharedWriters, so network_transaction ownership is transferred to
81 // SharedWriters. But if there are other transactions, entry will be doomed
82 // and this transaction will continue reading from the network so the return
83 // value will pass the ownership of the network transaction back to the
84 // transaction.
85 std::unique_ptr<HttpTransaction> OnValidationNoMatch(
86 Transaction* transaction,
87 std::unique_ptr<HttpTransaction> network_transaction,
88 RequestPriority priority);
89
90 // Invoked when DoneReading is invoked on a shared transaction. If
91 // current_writer_ is set, do nothing, else consider it a read completion
92 // and process accordingly.
93 void DoneReading(Transaction* transaction);
94
95 // Invoked when StopCaching is called for a shared writer transaction.
96 // It stops caching only if there are no other transactions in
97 // all_writers_.
98 bool StopCaching(Transaction* transaction);
99
100 // Moves all transactions eligible for shared writing from entry's
101 // pending_queue to waiting_for_validation_.
102 void MoveFromPendingQueue();
103
104 // Posts a task for invoking the io callback of the first transaction in
105 // waiting_for_validation_.
106 void ProcessFirstWaitingValidation();
107
108 // Removes a transaction from waiting_for_validation_ and invokes
109 // ResetShared on it.
110 bool RemoveWaitingTransaction(Transaction* transaction);
111
112 // Removes a transaction which is in all_writers_ but not currently waiting
113 // on Read.
114 void RemoveIdleWriter(Transaction* transaction);
115
116 // Removes a waiting_writer_ transaction.
117 void RemoveWaitingWriter(Transaction* transaction);
118
119 // Removes the currently validating transaction.
120 void RemoveValidatingTransaction(Transaction* transaction);
121
122 // Removes the transaction that is currently accessing data_access_.
123 void RemoveCurrentWriter(Transaction* transaction);
124
125 // Should the owner be able to reset this object? Returns false if
126 // SharedWriters is in a flow where it is about to destroy itself at the end
127 // of the flow.
128 bool CanReset();
129
130 // Returns true if this object is empty: no transactions in all_writers and
131 // waiting_for_validation_ and validating_transaction_.
132 bool empty();
133
134 friend class Transaction;
135
136 private:
137 // Runs the state transition loop. Resets and calls |callback_| on exit,
138 // unless the return value is ERR_IO_PENDING.
139 int DoLoop(int result);
140
141 // IO Completion callback function. May destroy this object if needed at the
142 // end of the processing.
143 void OnIOComplete(int result);
144
145 // State machine functions.
146 int DoNetworkRead();
147 int DoNetworkReadComplete(int result);
148 int DoCacheWriteData(int num_bytes);
149 int DoCacheWriteDataComplete(int result);
150 int DoCacheWriteTruncatedResponse();
151 int DoCacheWriteTruncatedResponseComplete(int result);
152
153 // Helper functions for callback.
154 //
155 // current_writer_ successfully read from the network.
156 void OnNetworkReadSuccess(int len);
157
158 // current_writer_ successfully wrote to the cache.
159 void OnCacheWriteSuccess(int result);
160
161 // current_writer_ fails to write data to the cache.
162 // It transfers the ownership of data_access_ to the transaction since shared
163 // writing can no longer continue, but current_writer_ can continue to read
164 // the remaning data from the network. Any waiting_writers_ will be
165 // notified of the failure. Any idle transactions or validating_transaction_
166 // will be set to a state so that they can fail any subsequent Read calls.
167 // Any transactions in waiting_for_validation_ will move to pending_queue.
168 void OnCacheWriteFailure();
169
170 // current_writer_ fails to read from the network. Both this transaction and
171 // any waiting_writers_ will return the failure code to their consumers.
172 // Any idle transactions or validating_transaction_ will be set to a
173 // state so that they can fail any subsequent Read calls.
174 // Any transactions in waiting_for_validation_ will move to pending_queue.
175 // Marking the entry as truncated will be attempted.
176 void OnNetworkReadFailure(int result);
177
178 // Helper function for doing the cleanup for failure scenarios such as those
179 // mentioned above.
180 void FailureCleanup(int error, bool continue_network_reading);
181
182 // Moves all transactions in waiting_for_validation_ to entry's
183 // pending_queue.
184 void MoveToPendingQueue();
185
186 // Notifies the waiting_writers_ of the result, by posting a task for each
187 // of them. While processing the task for a transaction, it's IO callback
188 // will be invoked.
189 void ProcessWaitingWriters(int result);
190
191 // First waiting_for_validation transaction's callback will be invoked.
192 void OnProcessFirstWaitingValidation();
193
194 // Removes the current_writer_ transaction from this object.
195 void ResetCurrentWriter(bool continue_network_reading = false);
196
197 // Sets the state of idle writers so that they can fail any subsequent
198 // Read.
199 void SetIdleWritersFailState(int result);
200
201 // When response is completely written, any idle writers are moved to
202 // entry_->readers.
203 void MoveIdleWritersToReaders();
204
205 // Helper function to let the validating_transaction_ continue being a part of
206 // SharedWriters.
207 void ValidationDoneContinue(Transaction* transaction,
208 RequestPriority priority);
209
210 // Helper function invoked when response is successfully written to the cache.
211 void ResponseDataComplete();
212
213 // Deletes itself. This is needed for callback scenarios where we no longer
214 // need shared writing. Entry will release ownership in the flow and
215 // SharedWriters will delete itself in the end of the flow.
216 void SelfDestroy();
217
218 enum State {
219 STATE_NONE,
220 STATE_NETWORK_READ,
221 STATE_NETWORK_READ_COMPLETE,
222 STATE_CACHE_WRITE_DATA,
223 STATE_CACHE_WRITE_DATA_COMPLETE,
224 STATE_CACHE_WRITE_TRUNCATED_RESPONSE,
225 STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE
226 };
227
228 State next_state_ = STATE_NONE;
Randy Smith (Not in Mondays) 2017/01/19 00:53:43 I think it's good to use either all in-declaration
shivanisha 2017/01/25 19:46:13 I have tried to keep all simple initializations he
229
230 // Http Cache.
231 base::WeakPtr<HttpCache> cache_;
232
233 // Owner of this object.
234 ActiveEntry* entry_ = nullptr;
235
236 std::unique_ptr<DataAccess> data_access_;
237
238 scoped_refptr<IOBuffer> read_buf_;
239 int io_buf_len_ = 0;
240 int write_len_ = 0;
241
242 // The cache transaction that is the current consumer of data_access_::Read
243 // or data_access_->CacheWrite and is waiting for the operation to be
244 // completed. This is used to ensure there is at most one consumer of
245 // data_access_. After the network read and cache write is successful and data
246 // written to cache, other waiting writers will be notified.
247 Transaction* current_writer_ = nullptr;
248
249 // This will point to the currently validating transaction.
250 // After the validation stage is successfully done, this transaction is
251 // added to all_writers_.
252 Transaction* validating_transaction_ = nullptr;
253
254 // If a transaction is currently set in validating_transaction_, these
255 // transactions will wait for that to complete and then the first of these
256 // will be assigned to validating_transaction_.
257 TransactionList waiting_for_validation_;
258
259 // These transactions are waiting on their Read calls when current_writer_
260 // is not null. After current_writer_ completes writing the data to the
261 // cache, their buffer would be filled with the data and their callback
262 // invoked.
263 struct WaitingWriter {
264 Transaction* transaction;
265 scoped_refptr<IOBuffer> read_buf;
266 int read_buf_len;
267 int write_len;
268 WaitingWriter(Transaction* transaction,
269 scoped_refptr<IOBuffer> read_buf,
270 int len);
271 ~WaitingWriter();
272 WaitingWriter(const WaitingWriter&);
273 };
274 typedef std::list<WaitingWriter> WaitingWritersList;
275 WaitingWritersList waiting_writers_;
Randy Smith (Not in Mondays) 2017/01/19 00:53:43 Suggestion: I'm finding the reader/writer nomencla
shivanisha 2017/01/20 16:00:09 active_transaction_ and waiting_for_read_ sound go
shivanisha 2017/01/25 19:46:13 Done.
276
277 // Includes a transaction if it is one of the following:
278 // 1. current_writer_ or,
279 // 2. member of waiting_writers_ or,
280 // 3. Waiting for Read to be invoked from the consumer.
281 TransactionSet all_writers_;
282
283 // Current priority of the request. If a higher priority transaction is
284 // added to all_writers_, the priority of data_access_->network_transaction_
285 // will be increased.
286 // todo (shivanisha@): If the higher priority request dies, we do not change
287 // the priority back to a lower one. Fix this. The priority should be the
288 // highest of the existing requests.
289 RequestPriority priority_ = DEFAULT_PRIORITY;
290
291 CompletionCallback callback_; // Consumer's callback.
292 CompletionCallback io_callback_;
293
294 bool destroy_ = false; // Should be destroyed at the end of this flow.
295
296 // Return value from network read. Saved so it could be returned to the
297 // consumer after marking the entry as truncated, if needed.
298 int network_read_rv_ = 0;
299
300 base::WeakPtrFactory<SharedWriters> weak_factory_;
301
302 DISALLOW_COPY_AND_ASSIGN(SharedWriters);
303 };
304
305 } // namespace net
306
307 #endif // NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698