OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "ppapi/shared_impl/tcp_socket_shared.h" | 5 #include "ppapi/shared_impl/tcp_socket_shared.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 Init(socket_id); | 37 Init(socket_id); |
38 } | 38 } |
39 | 39 |
40 TCPSocketShared::~TCPSocketShared() { | 40 TCPSocketShared::~TCPSocketShared() { |
41 } | 41 } |
42 | 42 |
43 void TCPSocketShared::OnConnectCompleted( | 43 void TCPSocketShared::OnConnectCompleted( |
44 int32_t result, | 44 int32_t result, |
45 const PP_NetAddress_Private& local_addr, | 45 const PP_NetAddress_Private& local_addr, |
46 const PP_NetAddress_Private& remote_addr) { | 46 const PP_NetAddress_Private& remote_addr) { |
| 47 // It is possible that |connect_callback_| is pending while |
| 48 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been |
| 49 // called, but a ConnectCompleted notification came earlier than the task to |
| 50 // abort |connect_callback_|. We don't want to update |connection_state_| or |
| 51 // other members in that case. |
47 if (connection_state_ != BEFORE_CONNECT || | 52 if (connection_state_ != BEFORE_CONNECT || |
48 !TrackedCallback::IsPending(connect_callback_)) { | 53 !TrackedCallback::IsPending(connect_callback_)) { |
49 NOTREACHED(); | |
50 return; | 54 return; |
51 } | 55 } |
52 | 56 |
53 result = OverridePPError(result); | 57 result = OverridePPError(result); |
54 if (result == PP_OK) { | 58 if (result == PP_OK) { |
55 local_addr_ = local_addr; | 59 local_addr_ = local_addr; |
56 remote_addr_ = remote_addr; | 60 remote_addr_ = remote_addr; |
57 connection_state_ = CONNECTED; | 61 connection_state_ = CONNECTED; |
58 } | 62 } |
59 connect_callback_->Run(result); | 63 connect_callback_->Run(result); |
60 } | 64 } |
61 | 65 |
62 void TCPSocketShared::OnSSLHandshakeCompleted( | 66 void TCPSocketShared::OnSSLHandshakeCompleted( |
63 bool succeeded, | 67 bool succeeded, |
64 const PPB_X509Certificate_Fields& certificate_fields) { | 68 const PPB_X509Certificate_Fields& certificate_fields) { |
| 69 // It is possible that |ssl_handshake_callback_| is pending while |
| 70 // |connection_state_| is not CONNECT: DisconnectImpl() has been |
| 71 // called, but a SSLHandshakeCompleted notification came earlier than the task |
| 72 // to abort |ssl_handshake_callback_|. We don't want to update |
| 73 // |connection_state_| or other members in that case. |
65 if (connection_state_ != CONNECTED || | 74 if (connection_state_ != CONNECTED || |
66 !TrackedCallback::IsPending(ssl_handshake_callback_)) { | 75 !TrackedCallback::IsPending(ssl_handshake_callback_)) { |
67 NOTREACHED(); | |
68 return; | 76 return; |
69 } | 77 } |
70 | 78 |
71 if (succeeded) { | 79 if (succeeded) { |
72 connection_state_ = SSL_CONNECTED; | 80 connection_state_ = SSL_CONNECTED; |
73 server_certificate_ = new PPB_X509Certificate_Private_Shared( | 81 server_certificate_ = new PPB_X509Certificate_Private_Shared( |
74 resource_type_, | 82 resource_type_, |
75 GetOwnerResource()->pp_instance(), | 83 GetOwnerResource()->pp_instance(), |
76 certificate_fields); | 84 certificate_fields); |
77 ssl_handshake_callback_->Run(PP_OK); | 85 ssl_handshake_callback_->Run(PP_OK); |
78 } else { | 86 } else { |
79 // The resource might be released in the callback so we need to hold | 87 // The resource might be released in the callback so we need to hold |
80 // a reference so we can Disconnect() first. | 88 // a reference so we can Disconnect() first. |
81 GetOwnerResource()->AddRef(); | 89 GetOwnerResource()->AddRef(); |
82 ssl_handshake_callback_->Run(PP_ERROR_FAILED); | 90 ssl_handshake_callback_->Run(PP_ERROR_FAILED); |
83 DisconnectImpl(); | 91 DisconnectImpl(); |
84 GetOwnerResource()->Release(); | 92 GetOwnerResource()->Release(); |
85 } | 93 } |
86 } | 94 } |
87 | 95 |
88 void TCPSocketShared::OnReadCompleted(int32_t result, | 96 void TCPSocketShared::OnReadCompleted(int32_t result, |
89 const std::string& data) { | 97 const std::string& data) { |
90 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_) { | 98 // It is possible that |read_callback_| is pending while |read_buffer_| is |
91 NOTREACHED(); | 99 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification |
| 100 // came earlier than the task to abort |read_callback_|. We shouldn't access |
| 101 // the buffer in that case. The user may have released it. |
| 102 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_) |
92 return; | 103 return; |
93 } | |
94 | 104 |
95 result = OverridePPError(result); | 105 result = OverridePPError(result); |
96 bool succeeded = result == PP_OK; | 106 bool succeeded = result == PP_OK; |
97 if (succeeded) { | 107 if (succeeded) { |
98 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); | 108 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); |
99 if (!data.empty()) | 109 if (!data.empty()) |
100 memcpy(read_buffer_, data.c_str(), data.size()); | 110 memcpy(read_buffer_, data.c_str(), data.size()); |
101 } | 111 } |
102 read_buffer_ = NULL; | 112 read_buffer_ = NULL; |
103 bytes_to_read_ = -1; | 113 bytes_to_read_ = -1; |
104 | 114 |
105 read_callback_->Run( | 115 read_callback_->Run( |
106 succeeded ? static_cast<int32_t>(data.size()) : result); | 116 succeeded ? static_cast<int32_t>(data.size()) : result); |
107 } | 117 } |
108 | 118 |
109 void TCPSocketShared::OnWriteCompleted(int32_t result) { | 119 void TCPSocketShared::OnWriteCompleted(int32_t result) { |
110 if (!TrackedCallback::IsPending(write_callback_)) { | 120 if (!TrackedCallback::IsPending(write_callback_)) |
111 NOTREACHED(); | |
112 return; | 121 return; |
113 } | |
114 | 122 |
115 result = OverridePPError(result); | 123 result = OverridePPError(result); |
116 write_callback_->Run(result); | 124 write_callback_->Run(result); |
117 } | 125 } |
118 | 126 |
119 void TCPSocketShared::OnSetOptionCompleted(int32_t result) { | 127 void TCPSocketShared::OnSetOptionCompleted(int32_t result) { |
120 if (set_option_callbacks_.empty()) { | 128 if (set_option_callbacks_.empty()) { |
121 NOTREACHED(); | 129 NOTREACHED(); |
122 return; | 130 return; |
123 } | 131 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; | 363 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; |
356 } | 364 } |
357 | 365 |
358 void TCPSocketShared::PostAbortIfNecessary( | 366 void TCPSocketShared::PostAbortIfNecessary( |
359 scoped_refptr<TrackedCallback>* callback) { | 367 scoped_refptr<TrackedCallback>* callback) { |
360 if (TrackedCallback::IsPending(*callback)) | 368 if (TrackedCallback::IsPending(*callback)) |
361 (*callback)->PostAbort(); | 369 (*callback)->PostAbort(); |
362 } | 370 } |
363 | 371 |
364 } // namespace ppapi | 372 } // namespace ppapi |
OLD | NEW |