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

Side by Side Diff: net/disk_cache/simple/simple_entry_impl.cc

Issue 12277004: Make SimpleEntryImpl::Close asynchronous. (Closed) Base URL: http://git.chromium.org/git/chromium.git@3-doomdoom
Patch Set: remediate Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "net/disk_cache/simple/simple_entry_impl.h" 5 #include "net/disk_cache/simple/simple_entry_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // underlying files. On POSIX, this is fine; the files are still open on the 79 // underlying files. On POSIX, this is fine; the files are still open on the
80 // SimpleSynchronousEntry, and operations can even happen on them. The files 80 // SimpleSynchronousEntry, and operations can even happen on them. The files
81 // will be removed from the filesystem when they are closed. 81 // will be removed from the filesystem when they are closed.
82 DoomEntry(path_, key_, CompletionCallback()); 82 DoomEntry(path_, key_, CompletionCallback());
83 #else 83 #else
84 NOTIMPLEMENTED(); 84 NOTIMPLEMENTED();
85 #endif 85 #endif
86 } 86 }
87 87
88 void SimpleEntryImpl::Close() { 88 void SimpleEntryImpl::Close() {
89 if (synchronous_entry_in_use_by_worker_) { 89 if (!synchronous_entry_in_use_by_worker_) {
90 NOTIMPLEMENTED(); 90 WorkerPool::PostTask(FROM_HERE,
91 delete this; 91 base::Bind(&SimpleSynchronousEntry::Close,
92 return; 92 base::Unretained(synchronous_entry_)),
93 true);
93 } 94 }
94 DCHECK(synchronous_entry_);
95 WorkerPool::PostTask(FROM_HERE,
96 base::Bind(&SimpleSynchronousEntry::Close,
97 base::Unretained(synchronous_entry_)),
98 true);
99 synchronous_entry_ = NULL;
100 // Entry::Close() is expected to release this entry. See disk_cache.h for 95 // Entry::Close() is expected to release this entry. See disk_cache.h for
101 // details. 96 // details.
102 delete this; 97 delete this;
103 } 98 }
104 99
105 std::string SimpleEntryImpl::GetKey() const { 100 std::string SimpleEntryImpl::GetKey() const {
106 return key_; 101 return key_;
107 } 102 }
108 103
109 Time SimpleEntryImpl::GetLastUsed() const { 104 Time SimpleEntryImpl::GetLastUsed() const {
110 return last_used_; 105 return last_used_;
111 } 106 }
112 107
113 Time SimpleEntryImpl::GetLastModified() const { 108 Time SimpleEntryImpl::GetLastModified() const {
114 return last_modified_; 109 return last_modified_;
115 } 110 }
116 111
117 int32 SimpleEntryImpl::GetDataSize(int index) const { 112 int32 SimpleEntryImpl::GetDataSize(int index) const {
118 return data_size_[index]; 113 return data_size_[index];
119 } 114 }
120 115
121 int SimpleEntryImpl::ReadData(int index, 116 int SimpleEntryImpl::ReadData(int index,
122 int offset, 117 int offset,
123 net::IOBuffer* buf, 118 net::IOBuffer* buf,
124 int buf_len, 119 int buf_len,
125 const CompletionCallback& callback) { 120 const CompletionCallback& callback) {
126 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does 121 // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does
127 // make overlapping read requests when multiple transactions access the same 122 // make overlapping read requests when multiple transactions access the same
128 // entry as read only. 123 // entry as read only. This might make calling SimpleSynchronousEntry::Close()
124 // correctly more tricky (see SimpleEntryImpl::EntryOperationComplete).
129 if (synchronous_entry_in_use_by_worker_) { 125 if (synchronous_entry_in_use_by_worker_) {
130 NOTIMPLEMENTED(); 126 NOTIMPLEMENTED();
131 CHECK(false); 127 CHECK(false);
132 } 128 }
133 synchronous_entry_in_use_by_worker_ = true; 129 synchronous_entry_in_use_by_worker_ = true;
134 SynchronousOperationCallback sync_operation_callback = 130 SynchronousOperationCallback sync_operation_callback =
135 base::Bind(&SimpleEntryImpl::EntryOperationComplete, 131 base::Bind(&SimpleEntryImpl::EntryOperationComplete,
136 callback, weak_ptr_factory_.GetWeakPtr()); 132 callback, weak_ptr_factory_.GetWeakPtr(), synchronous_entry_);
137 WorkerPool::PostTask(FROM_HERE, 133 WorkerPool::PostTask(FROM_HERE,
138 base::Bind(&SimpleSynchronousEntry::ReadData, 134 base::Bind(&SimpleSynchronousEntry::ReadData,
139 base::Unretained(synchronous_entry_), 135 base::Unretained(synchronous_entry_),
140 index, offset, make_scoped_refptr(buf), 136 index, offset, make_scoped_refptr(buf),
141 buf_len, sync_operation_callback), 137 buf_len, sync_operation_callback),
142 true); 138 true);
143 return net::ERR_IO_PENDING; 139 return net::ERR_IO_PENDING;
144 } 140 }
145 141
146 int SimpleEntryImpl::WriteData(int index, 142 int SimpleEntryImpl::WriteData(int index,
147 int offset, 143 int offset,
148 net::IOBuffer* buf, 144 net::IOBuffer* buf,
149 int buf_len, 145 int buf_len,
150 const CompletionCallback& callback, 146 const CompletionCallback& callback,
151 bool truncate) { 147 bool truncate) {
152 if (synchronous_entry_in_use_by_worker_) { 148 if (synchronous_entry_in_use_by_worker_) {
153 NOTIMPLEMENTED(); 149 NOTIMPLEMENTED();
154 CHECK(false); 150 CHECK(false);
155 } 151 }
156 synchronous_entry_in_use_by_worker_ = true; 152 synchronous_entry_in_use_by_worker_ = true;
157 SynchronousOperationCallback sync_operation_callback = 153 SynchronousOperationCallback sync_operation_callback =
158 base::Bind(&SimpleEntryImpl::EntryOperationComplete, 154 base::Bind(&SimpleEntryImpl::EntryOperationComplete,
159 callback, weak_ptr_factory_.GetWeakPtr()); 155 callback, weak_ptr_factory_.GetWeakPtr(), synchronous_entry_);
160 WorkerPool::PostTask(FROM_HERE, 156 WorkerPool::PostTask(FROM_HERE,
161 base::Bind(&SimpleSynchronousEntry::WriteData, 157 base::Bind(&SimpleSynchronousEntry::WriteData,
162 base::Unretained(synchronous_entry_), 158 base::Unretained(synchronous_entry_),
163 index, offset, make_scoped_refptr(buf), 159 index, offset, make_scoped_refptr(buf),
164 buf_len, sync_operation_callback, truncate), 160 buf_len, sync_operation_callback, truncate),
165 true); 161 true);
166 return net::ERR_IO_PENDING; 162 return net::ERR_IO_PENDING;
167 } 163 }
168 164
169 int SimpleEntryImpl::ReadSparseData(int64 offset, 165 int SimpleEntryImpl::ReadSparseData(int64 offset,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 210 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
215 path_(synchronous_entry->path()), 211 path_(synchronous_entry->path()),
216 key_(synchronous_entry->key()), 212 key_(synchronous_entry->key()),
217 synchronous_entry_(synchronous_entry), 213 synchronous_entry_(synchronous_entry),
218 synchronous_entry_in_use_by_worker_(false) { 214 synchronous_entry_in_use_by_worker_(false) {
219 DCHECK(synchronous_entry); 215 DCHECK(synchronous_entry);
220 SetSynchronousData(); 216 SetSynchronousData();
221 } 217 }
222 218
223 SimpleEntryImpl::~SimpleEntryImpl() { 219 SimpleEntryImpl::~SimpleEntryImpl() {
224 DCHECK(!synchronous_entry_);
225 } 220 }
226 221
227 // static 222 // static
228 void SimpleEntryImpl::CreationOperationComplete( 223 void SimpleEntryImpl::CreationOperationComplete(
229 const CompletionCallback& completion_callback, 224 const CompletionCallback& completion_callback,
230 Entry** out_entry, 225 Entry** out_entry,
231 SimpleSynchronousEntry* sync_entry) { 226 SimpleSynchronousEntry* sync_entry) {
232 if (!sync_entry) { 227 if (!sync_entry) {
233 completion_callback.Run(net::ERR_FAILED); 228 completion_callback.Run(net::ERR_FAILED);
234 return; 229 return;
235 } 230 }
236 *out_entry = new SimpleEntryImpl(sync_entry); 231 *out_entry = new SimpleEntryImpl(sync_entry);
237 completion_callback.Run(net::OK); 232 completion_callback.Run(net::OK);
238 } 233 }
239 234
240 // static 235 // static
241 void SimpleEntryImpl::EntryOperationComplete( 236 void SimpleEntryImpl::EntryOperationComplete(
242 const CompletionCallback& completion_callback, 237 const CompletionCallback& completion_callback,
243 base::WeakPtr<SimpleEntryImpl> entry, 238 base::WeakPtr<SimpleEntryImpl> entry,
239 SimpleSynchronousEntry* sync_entry,
244 int result) { 240 int result) {
245 if (entry) { 241 if (entry) {
246 DCHECK(entry->synchronous_entry_in_use_by_worker_); 242 DCHECK(entry->synchronous_entry_in_use_by_worker_);
247 entry->synchronous_entry_in_use_by_worker_ = false; 243 entry->synchronous_entry_in_use_by_worker_ = false;
248 entry->SetSynchronousData(); 244 entry->SetSynchronousData();
245 } else {
246 // |entry| must have had Close() called while this operation was in flight.
247 // Since the simple cache now only supports one pending entry operation in
248 // flight at a time, it's safe to now call Close() on |sync_entry|.
249 WorkerPool::PostTask(FROM_HERE,
250 base::Bind(&SimpleSynchronousEntry::Close,
251 base::Unretained(sync_entry)),
252 true);
249 } 253 }
250 completion_callback.Run(result); 254 completion_callback.Run(result);
251 } 255 }
252 256
253 void SimpleEntryImpl::SetSynchronousData() { 257 void SimpleEntryImpl::SetSynchronousData() {
254 DCHECK(!synchronous_entry_in_use_by_worker_); 258 DCHECK(!synchronous_entry_in_use_by_worker_);
255 259
256 // TODO(felipeg): These copies to avoid data races are not optimal. While 260 // TODO(felipeg): These copies to avoid data races are not optimal. While
257 // adding an IO thread index (for fast misses etc...), we can store this data 261 // adding an IO thread index (for fast misses etc...), we can store this data
258 // in that structure. This also solves problems with last_used() on ext4 262 // in that structure. This also solves problems with last_used() on ext4
259 // filesystems not being accurate. 263 // filesystems not being accurate.
260 264
261 last_used_ = synchronous_entry_->last_used(); 265 last_used_ = synchronous_entry_->last_used();
262 last_modified_ = synchronous_entry_->last_modified(); 266 last_modified_ = synchronous_entry_->last_modified();
263 for (int i = 0; i < kSimpleEntryFileCount; ++i) 267 for (int i = 0; i < kSimpleEntryFileCount; ++i)
264 data_size_[i] = synchronous_entry_->data_size(i); 268 data_size_[i] = synchronous_entry_->data_size(i);
265 } 269 }
266 270
267 } // namespace disk_cache 271 } // namespace disk_cache
OLDNEW
« net/disk_cache/simple/simple_entry_impl.h ('K') | « net/disk_cache/simple/simple_entry_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698