OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 return LOAD_STATE_IDLE; | 772 return LOAD_STATE_IDLE; |
773 } | 773 } |
774 | 774 |
775 void SpdySession::OnReadComplete(int bytes_read) { | 775 void SpdySession::OnReadComplete(int bytes_read) { |
776 // Parse a frame. For now this code requires that the frame fit into our | 776 // Parse a frame. For now this code requires that the frame fit into our |
777 // buffer (32KB). | 777 // buffer (32KB). |
778 // TODO(mbelshe): support arbitrarily large frames! | 778 // TODO(mbelshe): support arbitrarily large frames! |
779 | 779 |
780 read_pending_ = false; | 780 read_pending_ = false; |
781 | 781 |
782 bool can_do_more = ProcessBytesRead(bytes_read); | |
783 | |
784 if (can_do_more) | |
785 ReadSocket(); | |
786 } | |
787 | |
788 bool SpdySession::ProcessBytesRead(int bytes_read) { | |
782 if (bytes_read <= 0) { | 789 if (bytes_read <= 0) { |
783 // Session is tearing down. | 790 // Session is tearing down. |
784 net::Error error = static_cast<net::Error>(bytes_read); | 791 net::Error error = static_cast<net::Error>(bytes_read); |
785 if (bytes_read == 0) | 792 if (bytes_read == 0) |
786 error = ERR_CONNECTION_CLOSED; | 793 error = ERR_CONNECTION_CLOSED; |
787 CloseSessionOnError(error, true, "bytes_read is <= 0."); | 794 CloseSessionOnError(error, true, "bytes_read is <= 0."); |
788 return; | 795 return false; |
789 } | 796 } |
790 | 797 |
791 bytes_received_ += bytes_read; | 798 bytes_received_ += bytes_read; |
792 | 799 |
793 last_activity_time_ = base::TimeTicks::Now(); | 800 last_activity_time_ = base::TimeTicks::Now(); |
794 | 801 |
795 // The SpdyFramer will use callbacks onto |this| as it parses frames. | 802 // The SpdyFramer will use callbacks onto |this| as it parses frames. |
796 // When errors occur, those callbacks can lead to teardown of all references | 803 // When errors occur, those callbacks can lead to teardown of all references |
797 // to |this|, so maintain a reference to self during this call for safe | 804 // to |this|, so maintain a reference to self during this call for safe |
798 // cleanup. | 805 // cleanup. |
799 scoped_refptr<SpdySession> self(this); | 806 scoped_refptr<SpdySession> self(this); |
800 | 807 |
801 DCHECK(buffered_spdy_framer_.get()); | 808 DCHECK(buffered_spdy_framer_.get()); |
802 char *data = read_buffer_->data(); | 809 char *data = read_buffer_->data(); |
803 while (bytes_read && | 810 while (bytes_read && |
804 buffered_spdy_framer_->error_code() == | 811 buffered_spdy_framer_->error_code() == |
805 SpdyFramer::SPDY_NO_ERROR) { | 812 SpdyFramer::SPDY_NO_ERROR) { |
806 uint32 bytes_processed = | 813 uint32 bytes_processed = |
807 buffered_spdy_framer_->ProcessInput(data, bytes_read); | 814 buffered_spdy_framer_->ProcessInput(data, bytes_read); |
808 bytes_read -= bytes_processed; | 815 bytes_read -= bytes_processed; |
809 data += bytes_processed; | 816 data += bytes_processed; |
810 if (buffered_spdy_framer_->state() == SpdyFramer::SPDY_DONE) | 817 if (buffered_spdy_framer_->state() == SpdyFramer::SPDY_DONE) |
811 buffered_spdy_framer_->Reset(); | 818 buffered_spdy_framer_->Reset(); |
812 } | 819 } |
813 | 820 return state_ != CLOSED; |
814 if (state_ != CLOSED) | |
815 ReadSocket(); | |
816 } | 821 } |
817 | 822 |
818 void SpdySession::OnWriteComplete(int result) { | 823 void SpdySession::OnWriteComplete(int result) { |
819 DCHECK(write_pending_); | 824 DCHECK(write_pending_); |
820 DCHECK(in_flight_write_.size()); | 825 DCHECK(in_flight_write_.size()); |
821 | 826 |
822 last_activity_time_ = base::TimeTicks::Now(); | 827 last_activity_time_ = base::TimeTicks::Now(); |
823 write_pending_ = false; | 828 write_pending_ = false; |
824 | 829 |
825 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); | 830 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 } else { | 866 } else { |
862 in_flight_write_.release(); | 867 in_flight_write_.release(); |
863 | 868 |
864 // The stream is now errored. Close it down. | 869 // The stream is now errored. Close it down. |
865 CloseSessionOnError( | 870 CloseSessionOnError( |
866 static_cast<net::Error>(result), true, "The stream has errored."); | 871 static_cast<net::Error>(result), true, "The stream has errored."); |
867 } | 872 } |
868 } | 873 } |
869 | 874 |
870 net::Error SpdySession::ReadSocket() { | 875 net::Error SpdySession::ReadSocket() { |
871 if (read_pending_) | 876 bool can_do_more = false; |
872 return OK; | 877 net::Error result; |
878 do { | |
879 if (read_pending_) | |
880 return OK; | |
873 | 881 |
874 if (state_ == CLOSED) { | 882 if (state_ == CLOSED) { |
875 NOTREACHED(); | 883 NOTREACHED(); |
876 return ERR_UNEXPECTED; | 884 return ERR_UNEXPECTED; |
877 } | 885 } |
878 | 886 |
879 CHECK(connection_.get()); | 887 CHECK(connection_.get()); |
880 CHECK(connection_->socket()); | 888 CHECK(connection_->socket()); |
881 int bytes_read = connection_->socket()->Read( | 889 int bytes_read = connection_->socket()->Read( |
882 read_buffer_.get(), | 890 read_buffer_.get(), |
willchan no longer on Chromium
2012/12/24 00:19:35
don't we need to increment the offset we read into
Ryan Sleevi
2012/12/24 05:38:44
No, because ProcessBytesRead drains |read_buffer_|
| |
883 kReadBufferSize, | 891 kReadBufferSize, |
884 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); | 892 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); |
885 switch (bytes_read) { | 893 switch (bytes_read) { |
886 case 0: | 894 case 0: |
887 // Socket is closed! | 895 // Socket is closed! |
888 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); | 896 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); |
889 return ERR_CONNECTION_CLOSED; | 897 result = ERR_CONNECTION_CLOSED; |
890 case net::ERR_IO_PENDING: | 898 break; |
891 // Waiting for data. Nothing to do now. | 899 case net::ERR_IO_PENDING: |
892 read_pending_ = true; | 900 // Waiting for data. Nothing to do now. |
893 return ERR_IO_PENDING; | 901 read_pending_ = true; |
894 default: | 902 result = ERR_IO_PENDING; |
895 // Data was read, process it. | 903 break; |
896 // Schedule the work through the message loop to avoid recursive | 904 default: |
897 // callbacks. | 905 can_do_more = ProcessBytesRead(bytes_read); |
898 read_pending_ = true; | 906 result = OK; |
899 MessageLoop::current()->PostTask( | 907 break; |
900 FROM_HERE, | 908 } |
901 base::Bind(&SpdySession::OnReadComplete, | 909 } while (result == OK && can_do_more); |
Ryan Sleevi
2012/12/24 05:38:44
Like I expressed Friday, I'm a slightly concerned
Ryan Hamilton
2012/12/24 15:26:35
+1 on an explict STATE_DO_READ/STATE_DO_READ_COMPL
| |
902 weak_factory_.GetWeakPtr(), bytes_read)); | 910 return result; |
903 break; | |
904 } | |
905 return OK; | |
906 } | 911 } |
907 | 912 |
908 void SpdySession::WriteSocketLater() { | 913 void SpdySession::WriteSocketLater() { |
909 if (delayed_write_pending_) | 914 if (delayed_write_pending_) |
910 return; | 915 return; |
911 | 916 |
912 if (state_ < CONNECTED) | 917 if (state_ < CONNECTED) |
913 return; | 918 return; |
914 | 919 |
915 delayed_write_pending_ = true; | 920 delayed_write_pending_ = true; |
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1957 SSLClientSocket* SpdySession::GetSSLClientSocket() const { | 1962 SSLClientSocket* SpdySession::GetSSLClientSocket() const { |
1958 if (!is_secure_) | 1963 if (!is_secure_) |
1959 return NULL; | 1964 return NULL; |
1960 SSLClientSocket* ssl_socket = | 1965 SSLClientSocket* ssl_socket = |
1961 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1966 reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
1962 DCHECK(ssl_socket); | 1967 DCHECK(ssl_socket); |
1963 return ssl_socket; | 1968 return ssl_socket; |
1964 } | 1969 } |
1965 | 1970 |
1966 } // namespace net | 1971 } // namespace net |
OLD | NEW |