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

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

Issue 22859060: Fix race condition for non-open/create operations happening after a doom. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 3 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 <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/message_loop/message_loop_proxy.h" 16 #include "base/message_loop/message_loop_proxy.h"
17 #include "base/task_runner.h" 17 #include "base/task_runner.h"
18 #include "base/task_runner_util.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
19 #include "net/base/io_buffer.h" 20 #include "net/base/io_buffer.h"
20 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
21 #include "net/disk_cache/net_log_parameters.h" 22 #include "net/disk_cache/net_log_parameters.h"
22 #include "net/disk_cache/simple/simple_backend_impl.h" 23 #include "net/disk_cache/simple/simple_backend_impl.h"
23 #include "net/disk_cache/simple/simple_histogram_macros.h" 24 #include "net/disk_cache/simple/simple_histogram_macros.h"
24 #include "net/disk_cache/simple/simple_index.h" 25 #include "net/disk_cache/simple/simple_index.h"
25 #include "net/disk_cache/simple/simple_net_log_parameters.h" 26 #include "net/disk_cache/simple/simple_net_log_parameters.h"
26 #include "net/disk_cache/simple/simple_synchronous_entry.h" 27 #include "net/disk_cache/simple/simple_synchronous_entry.h"
27 #include "net/disk_cache/simple/simple_util.h" 28 #include "net/disk_cache/simple/simple_util.h"
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 258
258 RunNextOperationIfNeeded(); 259 RunNextOperationIfNeeded();
259 return ret_value; 260 return ret_value;
260 } 261 }
261 262
262 int SimpleEntryImpl::DoomEntry(const CompletionCallback& callback) { 263 int SimpleEntryImpl::DoomEntry(const CompletionCallback& callback) {
263 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_DOOM_CALL); 264 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_DOOM_CALL);
264 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_DOOM_BEGIN); 265 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_DOOM_BEGIN);
265 266
266 MarkAsDoomed(); 267 MarkAsDoomed();
267 scoped_ptr<int> result(new int()); 268 pending_operations_.push(SimpleEntryOperation::DoomOperation(this, callback));
268 Closure task = base::Bind(&SimpleSynchronousEntry::DoomEntry, path_, key_, 269 RunNextOperationIfNeeded();
269 entry_hash_, result.get());
270 Closure reply = base::Bind(&CallCompletionCallback,
271 callback, base::Passed(&result));
272 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply);
273 return net::ERR_IO_PENDING; 270 return net::ERR_IO_PENDING;
274 } 271 }
275 272
276 void SimpleEntryImpl::SetKey(const std::string& key) { 273 void SimpleEntryImpl::SetKey(const std::string& key) {
277 key_ = key; 274 key_ = key;
278 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_SET_KEY, 275 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_SET_KEY,
279 net::NetLog::StringCallback("key", &key)); 276 net::NetLog::StringCallback("key", &key));
280 } 277 }
281 278
282 void SimpleEntryImpl::Doom() { 279 void SimpleEntryImpl::Doom() {
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 break; 577 break;
581 case SimpleEntryOperation::TYPE_WRITE: 578 case SimpleEntryOperation::TYPE_WRITE:
582 RecordWriteDependencyType(*operation); 579 RecordWriteDependencyType(*operation);
583 WriteDataInternal(operation->index(), 580 WriteDataInternal(operation->index(),
584 operation->offset(), 581 operation->offset(),
585 operation->buf(), 582 operation->buf(),
586 operation->length(), 583 operation->length(),
587 operation->callback(), 584 operation->callback(),
588 operation->truncate()); 585 operation->truncate());
589 break; 586 break;
587 case SimpleEntryOperation::TYPE_DOOM:
588 DoomEntryInternal(operation->callback());
589 break;
590 default: 590 default:
591 NOTREACHED(); 591 NOTREACHED();
592 } 592 }
593 // The operation is kept for histograms. Makes sure it does not leak 593 // The operation is kept for histograms. Makes sure it does not leak
594 // resources. 594 // resources.
595 executing_operation_.swap(operation); 595 executing_operation_.swap(operation);
596 executing_operation_->ReleaseReferences(); 596 executing_operation_->ReleaseReferences();
597 // |this| may have been deleted. 597 // |this| may have been deleted.
598 } 598 }
599 } 599 }
600 600
601 void SimpleEntryImpl::OpenEntryInternal(bool have_index, 601 void SimpleEntryImpl::OpenEntryInternal(bool have_index,
602 const CompletionCallback& callback, 602 const CompletionCallback& callback,
603 Entry** out_entry) { 603 Entry** out_entry) {
604 ScopedOperationRunner operation_runner(this); 604 ScopedOperationRunner operation_runner(this);
605 605
606 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_BEGIN); 606 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_BEGIN);
607 607
608 if (state_ == STATE_READY) { 608 if (state_ == STATE_READY) {
609 ReturnEntryToCaller(out_entry); 609 ReturnEntryToCaller(out_entry);
610 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(callback, 610 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(callback,
611 net::OK)); 611 net::OK));
612 net_log_.AddEvent( 612 net_log_.AddEvent(
613 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_END, 613 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_END,
614 CreateNetLogSimpleEntryCreationCallback(this, net::OK)); 614 CreateNetLogSimpleEntryCreationCallback(this, net::OK));
615 return; 615 return;
616 } else if (state_ == STATE_FAILURE) { 616 }
617 if (state_ == STATE_FAILURE) {
617 if (!callback.is_null()) { 618 if (!callback.is_null()) {
618 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( 619 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(
619 callback, net::ERR_FAILED)); 620 callback, net::ERR_FAILED));
620 } 621 }
621 net_log_.AddEvent( 622 net_log_.AddEvent(
622 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_END, 623 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_OPEN_END,
623 CreateNetLogSimpleEntryCreationCallback(this, net::ERR_FAILED)); 624 CreateNetLogSimpleEntryCreationCallback(this, net::ERR_FAILED));
624 return; 625 return;
625 } 626 }
626 627
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); 737 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply);
737 738
738 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 739 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
739 if (!have_written_[i]) { 740 if (!have_written_[i]) {
740 SIMPLE_CACHE_UMA(ENUMERATION, 741 SIMPLE_CACHE_UMA(ENUMERATION,
741 "CheckCRCResult", cache_type_, 742 "CheckCRCResult", cache_type_,
742 crc_check_state_[i], CRC_CHECK_MAX); 743 crc_check_state_[i], CRC_CHECK_MAX);
743 } 744 }
744 } 745 }
745 } else { 746 } else {
746 synchronous_entry_ = NULL;
747 CloseOperationComplete(); 747 CloseOperationComplete();
748 } 748 }
749 } 749 }
750 750
751 void SimpleEntryImpl::ReadDataInternal(int stream_index, 751 void SimpleEntryImpl::ReadDataInternal(int stream_index,
752 int offset, 752 int offset,
753 net::IOBuffer* buf, 753 net::IOBuffer* buf,
754 int buf_len, 754 int buf_len,
755 const CompletionCallback& callback) { 755 const CompletionCallback& callback) {
756 DCHECK(io_thread_checker_.CalledOnValidThread()); 756 DCHECK(io_thread_checker_.CalledOnValidThread());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 result.get()); 894 result.get());
895 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, 895 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete,
896 this, 896 this,
897 stream_index, 897 stream_index,
898 callback, 898 callback,
899 base::Passed(&entry_stat), 899 base::Passed(&entry_stat),
900 base::Passed(&result)); 900 base::Passed(&result));
901 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); 901 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply);
902 } 902 }
903 903
904 void SimpleEntryImpl::DoomEntryInternal(const CompletionCallback& callback) {
905 PostTaskAndReplyWithResult(
906 worker_pool_, FROM_HERE,
907 base::Bind(&SimpleSynchronousEntry::DoomEntry, path_, key_, entry_hash_),
908 base::Bind(&SimpleEntryImpl::DoomOperationComplete, this, callback,
909 state_));
910 state_ = STATE_IO_PENDING;
911 }
912
904 void SimpleEntryImpl::CreationOperationComplete( 913 void SimpleEntryImpl::CreationOperationComplete(
905 const CompletionCallback& completion_callback, 914 const CompletionCallback& completion_callback,
906 const base::TimeTicks& start_time, 915 const base::TimeTicks& start_time,
907 scoped_ptr<SimpleEntryCreationResults> in_results, 916 scoped_ptr<SimpleEntryCreationResults> in_results,
908 Entry** out_entry, 917 Entry** out_entry,
909 net::NetLog::EventType end_event_type) { 918 net::NetLog::EventType end_event_type) {
910 DCHECK(io_thread_checker_.CalledOnValidThread()); 919 DCHECK(io_thread_checker_.CalledOnValidThread());
911 DCHECK_EQ(state_, STATE_IO_PENDING); 920 DCHECK_EQ(state_, STATE_IO_PENDING);
912 DCHECK(in_results); 921 DCHECK(in_results);
913 ScopedOperationRunner operation_runner(this); 922 ScopedOperationRunner operation_runner(this);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 RecordWriteResult(cache_type_, WRITE_RESULT_SYNC_WRITE_FAILURE); 1075 RecordWriteResult(cache_type_, WRITE_RESULT_SYNC_WRITE_FAILURE);
1067 if (net_log_.IsLoggingAllEvents()) { 1076 if (net_log_.IsLoggingAllEvents()) {
1068 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, 1077 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END,
1069 CreateNetLogReadWriteCompleteCallback(*result)); 1078 CreateNetLogReadWriteCompleteCallback(*result));
1070 } 1079 }
1071 1080
1072 EntryOperationComplete( 1081 EntryOperationComplete(
1073 stream_index, completion_callback, *entry_stat, result.Pass()); 1082 stream_index, completion_callback, *entry_stat, result.Pass());
1074 } 1083 }
1075 1084
1085 void SimpleEntryImpl::DoomOperationComplete(const CompletionCallback& callback,
1086 State state_to_restore,
1087 int result) {
1088 state_ = state_to_restore;
1089 if (!callback.is_null())
1090 callback.Run(result);
1091 RunNextOperationIfNeeded();
1092 }
1093
1076 void SimpleEntryImpl::ChecksumOperationComplete( 1094 void SimpleEntryImpl::ChecksumOperationComplete(
1077 int orig_result, 1095 int orig_result,
1078 int stream_index, 1096 int stream_index,
1079 const CompletionCallback& completion_callback, 1097 const CompletionCallback& completion_callback,
1080 scoped_ptr<int> result) { 1098 scoped_ptr<int> result) {
1081 DCHECK(io_thread_checker_.CalledOnValidThread()); 1099 DCHECK(io_thread_checker_.CalledOnValidThread());
1082 DCHECK(synchronous_entry_); 1100 DCHECK(synchronous_entry_);
1083 DCHECK_EQ(STATE_IO_PENDING, state_); 1101 DCHECK_EQ(STATE_IO_PENDING, state_);
1084 DCHECK(result); 1102 DCHECK(result);
1085 1103
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE 1228 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE
1211 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; 1229 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE;
1212 } 1230 }
1213 } 1231 }
1214 SIMPLE_CACHE_UMA(ENUMERATION, 1232 SIMPLE_CACHE_UMA(ENUMERATION,
1215 "WriteDependencyType", cache_type_, 1233 "WriteDependencyType", cache_type_,
1216 type, WRITE_DEPENDENCY_TYPE_MAX); 1234 type, WRITE_DEPENDENCY_TYPE_MAX);
1217 } 1235 }
1218 1236
1219 } // namespace disk_cache 1237 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | net/disk_cache/simple/simple_entry_operation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698