cronet_upload_data_stream.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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
  3. // found in the LICENSE file.
  4. #include "components/cronet/cronet_upload_data_stream.h"
  5. #include "net/base/io_buffer.h"
  6. #include "net/base/net_errors.h"
  7. namespace cronet {
  8. CronetUploadDataStream::CronetUploadDataStream(Delegate* delegate, int64_t size)
  9. : UploadDataStream(size < 0, 0),
  10. size_(size),
  11. waiting_on_read_(false),
  12. read_in_progress_(false),
  13. waiting_on_rewind_(false),
  14. rewind_in_progress_(false),
  15. at_front_of_stream_(true),
  16. delegate_(delegate) {}
  17. CronetUploadDataStream::~CronetUploadDataStream() {
  18. delegate_->OnUploadDataStreamDestroyed();
  19. }
  20. int CronetUploadDataStream::InitInternal(const net::NetLogWithSource& net_log) {
  21. // ResetInternal should have been called before init, if the stream was in
  22. // use.
  23. DCHECK(!waiting_on_read_);
  24. DCHECK(!waiting_on_rewind_);
  25. if (!weak_factory_.HasWeakPtrs())
  26. delegate_->InitializeOnNetworkThread(weak_factory_.GetWeakPtr());
  27. // Set size of non-chunked uploads.
  28. if (size_ >= 0)
  29. SetSize(static_cast<uint64_t>(size_));
  30. // If already at the front of the stream, nothing to do.
  31. if (at_front_of_stream_) {
  32. // Being at the front of the stream implies there's no read or rewind in
  33. // progress.
  34. DCHECK(!read_in_progress_);
  35. DCHECK(!rewind_in_progress_);
  36. return net::OK;
  37. }
  38. // Otherwise, the request is now waiting for the stream to be rewound.
  39. waiting_on_rewind_ = true;
  40. // Start rewinding the stream if no operation is in progress.
  41. if (!read_in_progress_ && !rewind_in_progress_)
  42. StartRewind();
  43. return net::ERR_IO_PENDING;
  44. }
  45. int CronetUploadDataStream::ReadInternal(net::IOBuffer* buf, int buf_len) {
  46. // All pending operations should have completed before a read can start.
  47. DCHECK(!waiting_on_read_);
  48. DCHECK(!read_in_progress_);
  49. DCHECK(!waiting_on_rewind_);
  50. DCHECK(!rewind_in_progress_);
  51. DCHECK(buf);
  52. DCHECK_GT(buf_len, 0);
  53. read_in_progress_ = true;
  54. waiting_on_read_ = true;
  55. at_front_of_stream_ = false;
  56. scoped_refptr<net::IOBuffer> buffer(base::WrapRefCounted(buf));
  57. delegate_->Read(std::move(buffer), buf_len);
  58. return net::ERR_IO_PENDING;
  59. }
  60. void CronetUploadDataStream::ResetInternal() {
  61. // Consumer is not waiting on any operation. Note that the active operation,
  62. // if any, will continue.
  63. waiting_on_read_ = false;
  64. waiting_on_rewind_ = false;
  65. }
  66. void CronetUploadDataStream::OnReadSuccess(int bytes_read, bool final_chunk) {
  67. DCHECK(read_in_progress_);
  68. DCHECK(!rewind_in_progress_);
  69. DCHECK(bytes_read > 0 || (final_chunk && bytes_read == 0));
  70. if (!is_chunked()) {
  71. DCHECK(!final_chunk);
  72. }
  73. read_in_progress_ = false;
  74. if (waiting_on_rewind_) {
  75. DCHECK(!waiting_on_read_);
  76. // Since a read just completed, can't be at the front of the stream.
  77. StartRewind();
  78. return;
  79. }
  80. // ResetInternal has been called, but still waiting on InitInternal.
  81. if (!waiting_on_read_)
  82. return;
  83. waiting_on_read_ = false;
  84. if (final_chunk)
  85. SetIsFinalChunk();
  86. OnReadCompleted(bytes_read);
  87. }
  88. void CronetUploadDataStream::OnRewindSuccess() {
  89. DCHECK(!waiting_on_read_);
  90. DCHECK(!read_in_progress_);
  91. DCHECK(rewind_in_progress_);
  92. DCHECK(!at_front_of_stream_);
  93. rewind_in_progress_ = false;
  94. at_front_of_stream_ = true;
  95. // Possible that ResetInternal was called since the rewind was started, but
  96. // InitInternal has not been.
  97. if (!waiting_on_rewind_)
  98. return;
  99. waiting_on_rewind_ = false;
  100. OnInitCompleted(net::OK);
  101. }
  102. void CronetUploadDataStream::StartRewind() {
  103. DCHECK(!waiting_on_read_);
  104. DCHECK(!read_in_progress_);
  105. DCHECK(waiting_on_rewind_);
  106. DCHECK(!rewind_in_progress_);
  107. DCHECK(!at_front_of_stream_);
  108. rewind_in_progress_ = true;
  109. delegate_->Rewind();
  110. }
  111. } // namespace cronet