OLD | NEW |
---|---|
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 <limits> | 9 #include <limits> |
10 #include <utility> | 10 #include <utility> |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 buf_len < 0) { | 369 buf_len < 0) { |
370 if (net_log_.IsCapturing()) { | 370 if (net_log_.IsCapturing()) { |
371 net_log_.AddEvent( | 371 net_log_.AddEvent( |
372 net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, | 372 net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, |
373 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); | 373 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); |
374 } | 374 } |
375 | 375 |
376 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); | 376 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); |
377 return net::ERR_INVALID_ARGUMENT; | 377 return net::ERR_INVALID_ARGUMENT; |
378 } | 378 } |
379 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) || | |
380 offset < 0 || !buf_len)) { | |
381 if (net_log_.IsCapturing()) { | |
382 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, | |
383 CreateNetLogReadWriteCompleteCallback(0)); | |
384 } | |
385 | 379 |
386 RecordReadResult(cache_type_, READ_RESULT_NONBLOCK_EMPTY_RETURN); | 380 bool alone_in_queue = |
387 return 0; | 381 pending_operations_.size() == 0 && state_ == STATE_READY; |
382 | |
383 if (alone_in_queue) { | |
384 return ReadDataInternal(true, stream_index, offset, buf, buf_len, callback); | |
388 } | 385 } |
389 | 386 |
390 // TODO(clamy): return immediatly when reading from stream 0. | |
391 | |
392 // TODO(felipeg): Optimization: Add support for truly parallel read | |
393 // operations. | |
394 bool alone_in_queue = | |
395 pending_operations_.size() == 0 && state_ == STATE_READY; | |
396 pending_operations_.push(SimpleEntryOperation::ReadOperation( | 387 pending_operations_.push(SimpleEntryOperation::ReadOperation( |
397 this, stream_index, offset, buf_len, buf, callback, alone_in_queue)); | 388 this, stream_index, offset, buf_len, buf, callback, alone_in_queue)); |
398 RunNextOperationIfNeeded(); | 389 RunNextOperationIfNeeded(); |
399 return net::ERR_IO_PENDING; | 390 return net::ERR_IO_PENDING; |
400 } | 391 } |
401 | 392 |
402 int SimpleEntryImpl::WriteData(int stream_index, | 393 int SimpleEntryImpl::WriteData(int stream_index, |
403 int offset, | 394 int offset, |
404 net::IOBuffer* buf, | 395 net::IOBuffer* buf, |
405 int buf_len, | 396 int buf_len, |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 case SimpleEntryOperation::TYPE_CREATE: | 623 case SimpleEntryOperation::TYPE_CREATE: |
633 CreateEntryInternal(operation->have_index(), | 624 CreateEntryInternal(operation->have_index(), |
634 operation->callback(), | 625 operation->callback(), |
635 operation->out_entry()); | 626 operation->out_entry()); |
636 break; | 627 break; |
637 case SimpleEntryOperation::TYPE_CLOSE: | 628 case SimpleEntryOperation::TYPE_CLOSE: |
638 CloseInternal(); | 629 CloseInternal(); |
639 break; | 630 break; |
640 case SimpleEntryOperation::TYPE_READ: | 631 case SimpleEntryOperation::TYPE_READ: |
641 RecordReadIsParallelizable(*operation); | 632 RecordReadIsParallelizable(*operation); |
642 ReadDataInternal(operation->index(), | 633 ReadDataInternal(false, operation->index(), operation->offset(), |
643 operation->offset(), | 634 operation->buf(), operation->length(), |
644 operation->buf(), | |
645 operation->length(), | |
646 operation->callback()); | 635 operation->callback()); |
647 break; | 636 break; |
648 case SimpleEntryOperation::TYPE_WRITE: | 637 case SimpleEntryOperation::TYPE_WRITE: |
649 RecordWriteDependencyType(*operation); | 638 RecordWriteDependencyType(*operation); |
650 WriteDataInternal(operation->index(), | 639 WriteDataInternal(operation->index(), |
651 operation->offset(), | 640 operation->offset(), |
652 operation->buf(), | 641 operation->buf(), |
653 operation->length(), | 642 operation->length(), |
654 operation->callback(), | 643 operation->callback(), |
655 operation->truncate()); | 644 operation->truncate()); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 SIMPLE_CACHE_UMA(ENUMERATION, | 800 SIMPLE_CACHE_UMA(ENUMERATION, |
812 "CheckCRCResult", cache_type_, | 801 "CheckCRCResult", cache_type_, |
813 crc_check_state_[i], CRC_CHECK_MAX); | 802 crc_check_state_[i], CRC_CHECK_MAX); |
814 } | 803 } |
815 } | 804 } |
816 } else { | 805 } else { |
817 CloseOperationComplete(); | 806 CloseOperationComplete(); |
818 } | 807 } |
819 } | 808 } |
820 | 809 |
821 void SimpleEntryImpl::ReadDataInternal(int stream_index, | 810 int SimpleEntryImpl::ReadDataInternal(bool try_sync, |
822 int offset, | 811 int stream_index, |
823 net::IOBuffer* buf, | 812 int offset, |
824 int buf_len, | 813 net::IOBuffer* buf, |
825 const CompletionCallback& callback) { | 814 int buf_len, |
815 const CompletionCallback& callback) { | |
826 DCHECK(io_thread_checker_.CalledOnValidThread()); | 816 DCHECK(io_thread_checker_.CalledOnValidThread()); |
827 ScopedOperationRunner operation_runner(this); | 817 ScopedOperationRunner operation_runner(this); |
828 | 818 |
829 if (net_log_.IsCapturing()) { | 819 if (net_log_.IsCapturing()) { |
830 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN, | 820 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN, |
831 CreateNetLogReadWriteDataCallback(stream_index, offset, | 821 CreateNetLogReadWriteDataCallback(stream_index, offset, |
832 buf_len, false)); | 822 buf_len, false)); |
833 } | 823 } |
834 | 824 |
835 if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) { | 825 if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) { |
836 if (!callback.is_null()) { | 826 if (!callback.is_null() && !try_sync) { |
837 RecordReadResult(cache_type_, READ_RESULT_BAD_STATE); | 827 RecordReadResult(cache_type_, READ_RESULT_BAD_STATE); |
Maks Orlovich
2017/04/12 14:55:49
I should probably double-check the condition for t
pasko
2017/04/12 16:12:51
this won't appear on the benchmark, so why bother?
| |
838 // Note that the API states that client-provided callbacks for entry-level | 828 // Note that the API states that client-provided callbacks for entry-level |
839 // (i.e. non-backend) operations (e.g. read, write) are invoked even if | 829 // (i.e. non-backend) operations (e.g. read, write) are invoked even if |
840 // the backend was already destroyed. | 830 // the backend was already destroyed. |
841 base::ThreadTaskRunnerHandle::Get()->PostTask( | 831 base::ThreadTaskRunnerHandle::Get()->PostTask( |
842 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); | 832 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); |
843 } | 833 } |
844 if (net_log_.IsCapturing()) { | 834 if (net_log_.IsCapturing()) { |
845 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, | 835 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, |
846 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); | 836 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); |
847 } | 837 } |
848 return; | 838 return net::ERR_FAILED; |
849 } | 839 } |
850 DCHECK_EQ(STATE_READY, state_); | 840 DCHECK_EQ(STATE_READY, state_); |
851 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { | 841 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { |
852 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); | 842 RecordReadResult(cache_type_, try_sync ? READ_RESULT_NONBLOCK_EMPTY_RETURN |
843 : READ_RESULT_FAST_EMPTY_RETURN); | |
853 // If there is nothing to read, we bail out before setting state_ to | 844 // If there is nothing to read, we bail out before setting state_ to |
854 // STATE_IO_PENDING. | 845 // STATE_IO_PENDING. |
855 if (!callback.is_null()) | 846 if (!callback.is_null() && !try_sync) |
856 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 847 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
857 base::Bind(callback, 0)); | 848 base::Bind(callback, 0)); |
858 return; | 849 return 0; |
859 } | 850 } |
860 | 851 |
861 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); | 852 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); |
862 | 853 |
863 // Since stream 0 data is kept in memory, it is read immediately. | 854 // Since stream 0 data is kept in memory, it is read immediately. |
864 if (stream_index == 0) { | 855 if (stream_index == 0) { |
865 int ret_value = ReadStream0Data(buf, offset, buf_len); | 856 int ret_value = ReadStream0Data(buf, offset, buf_len); |
866 if (!callback.is_null()) { | 857 if (!callback.is_null() && !try_sync) { |
867 base::ThreadTaskRunnerHandle::Get()->PostTask( | 858 base::ThreadTaskRunnerHandle::Get()->PostTask( |
868 FROM_HERE, base::Bind(callback, ret_value)); | 859 FROM_HERE, base::Bind(callback, ret_value)); |
869 } | 860 } |
870 return; | 861 return ret_value; |
871 } | 862 } |
872 | 863 |
873 state_ = STATE_IO_PENDING; | 864 state_ = STATE_IO_PENDING; |
874 if (!doomed_ && backend_.get()) | 865 if (!doomed_ && backend_.get()) |
875 backend_->index()->UseIfExists(entry_hash_); | 866 backend_->index()->UseIfExists(entry_hash_); |
876 | 867 |
877 std::unique_ptr<uint32_t> read_crc32(new uint32_t()); | 868 std::unique_ptr<uint32_t> read_crc32(new uint32_t()); |
878 std::unique_ptr<int> result(new int()); | 869 std::unique_ptr<int> result(new int()); |
879 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat( | 870 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat( |
880 last_used_, last_modified_, data_size_, sparse_data_size_)); | 871 last_used_, last_modified_, data_size_, sparse_data_size_)); |
881 Closure task = base::Bind( | 872 Closure task = base::Bind( |
882 &SimpleSynchronousEntry::ReadData, base::Unretained(synchronous_entry_), | 873 &SimpleSynchronousEntry::ReadData, base::Unretained(synchronous_entry_), |
883 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), | 874 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), |
884 base::RetainedRef(buf), read_crc32.get(), entry_stat.get(), result.get()); | 875 base::RetainedRef(buf), read_crc32.get(), entry_stat.get(), result.get()); |
885 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, | 876 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, |
886 this, | 877 this, |
887 stream_index, | 878 stream_index, |
888 offset, | 879 offset, |
889 callback, | 880 callback, |
890 base::Passed(&read_crc32), | 881 base::Passed(&read_crc32), |
891 base::Passed(&entry_stat), | 882 base::Passed(&entry_stat), |
892 base::Passed(&result)); | 883 base::Passed(&result)); |
893 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 884 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
885 return net::ERR_IO_PENDING; | |
894 } | 886 } |
895 | 887 |
896 void SimpleEntryImpl::WriteDataInternal(int stream_index, | 888 void SimpleEntryImpl::WriteDataInternal(int stream_index, |
897 int offset, | 889 int offset, |
898 net::IOBuffer* buf, | 890 net::IOBuffer* buf, |
899 int buf_len, | 891 int buf_len, |
900 const CompletionCallback& callback, | 892 const CompletionCallback& callback, |
901 bool truncate) { | 893 bool truncate) { |
902 DCHECK(io_thread_checker_.CalledOnValidThread()); | 894 DCHECK(io_thread_checker_.CalledOnValidThread()); |
903 ScopedOperationRunner operation_runner(this); | 895 ScopedOperationRunner operation_runner(this); |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1562 } | 1554 } |
1563 crc32s_end_offset_[stream_index] = offset + length; | 1555 crc32s_end_offset_[stream_index] = offset + length; |
1564 } else if (offset < crc32s_end_offset_[stream_index]) { | 1556 } else if (offset < crc32s_end_offset_[stream_index]) { |
1565 // If a range for which the crc32 was already computed is rewritten, the | 1557 // If a range for which the crc32 was already computed is rewritten, the |
1566 // computation of the crc32 need to start from 0 again. | 1558 // computation of the crc32 need to start from 0 again. |
1567 crc32s_end_offset_[stream_index] = 0; | 1559 crc32s_end_offset_[stream_index] = 0; |
1568 } | 1560 } |
1569 } | 1561 } |
1570 | 1562 |
1571 } // namespace disk_cache | 1563 } // namespace disk_cache |
OLD | NEW |