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

Side by Side Diff: ppapi/shared_impl/private/tcp_socket_private_impl.cc

Issue 8804006: Reland 8688002: PPB_TCPSocket_Private/PPB_UDPSocket_Private are exposed to Browser (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix destruction issue Created 9 years 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
(Empty)
1 // Copyright (c) 2011 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
5 #include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
6
7 #include <string.h>
8
9 #include <algorithm>
10
11 #include "base/basictypes.h"
12 #include "base/bind.h"
13 #include "base/logging.h"
14 #include "base/message_loop.h"
15 #include "ppapi/c/pp_completion_callback.h"
16 #include "ppapi/c/pp_errors.h"
17
18 namespace ppapi {
19
20 namespace {
21
22 void AbortCallback(PP_CompletionCallback callback) {
23 PP_RunCompletionCallback(&callback, PP_ERROR_ABORTED);
24 }
25
26 } // namespace
27
28 const int32_t TCPSocketPrivateImpl::kMaxReadSize = 1024 * 1024;
29 const int32_t TCPSocketPrivateImpl::kMaxWriteSize = 1024 * 1024;
30
31 TCPSocketPrivateImpl::TCPSocketPrivateImpl(PP_Instance instance,
32 uint32 socket_id)
33 : Resource(instance) {
34 Init(socket_id);
35 }
36
37 TCPSocketPrivateImpl::TCPSocketPrivateImpl(const HostResource& resource,
38 uint32 socket_id)
39 : Resource(resource) {
40 Init(socket_id);
41 }
42
43 TCPSocketPrivateImpl::~TCPSocketPrivateImpl() {
44 }
45
46 thunk::PPB_TCPSocket_Private_API*
47 TCPSocketPrivateImpl::AsPPB_TCPSocket_Private_API() {
48 return this;
49 }
50
51 int32_t TCPSocketPrivateImpl::Connect(const char* host,
52 uint16_t port,
53 PP_CompletionCallback callback) {
54 if (!host)
55 return PP_ERROR_BADARGUMENT;
56 if (!callback.func)
57 return PP_ERROR_BLOCKS_MAIN_THREAD;
58 if (connection_state_ != BEFORE_CONNECT)
59 return PP_ERROR_FAILED;
60 if (connect_callback_.func)
61 return PP_ERROR_INPROGRESS; // Can only have one pending request.
62
63 connect_callback_ = callback;
64 // Send the request, the browser will call us back via ConnectACK.
65 SendConnect(host, port);
66 return PP_OK_COMPLETIONPENDING;
67 }
68
69 int32_t TCPSocketPrivateImpl::ConnectWithNetAddress(
70 const PP_NetAddress_Private* addr,
71 PP_CompletionCallback callback) {
72 if (!addr)
73 return PP_ERROR_BADARGUMENT;
74 if (!callback.func)
75 return PP_ERROR_BLOCKS_MAIN_THREAD;
76 if (connection_state_ != BEFORE_CONNECT)
77 return PP_ERROR_FAILED;
78 if (connect_callback_.func)
79 return PP_ERROR_INPROGRESS; // Can only have one pending request.
80
81 connect_callback_ = callback;
82 // Send the request, the browser will call us back via ConnectACK.
83 SendConnectWithNetAddress(*addr);
84 return PP_OK_COMPLETIONPENDING;
85 }
86
87 PP_Bool TCPSocketPrivateImpl::GetLocalAddress(
88 PP_NetAddress_Private* local_addr) {
89 if (!IsConnected() || !local_addr)
90 return PP_FALSE;
91
92 *local_addr = local_addr_;
93 return PP_TRUE;
94 }
95
96 PP_Bool TCPSocketPrivateImpl::GetRemoteAddress(
97 PP_NetAddress_Private* remote_addr) {
98 if (!IsConnected() || !remote_addr)
99 return PP_FALSE;
100
101 *remote_addr = remote_addr_;
102 return PP_TRUE;
103 }
104
105 int32_t TCPSocketPrivateImpl::SSLHandshake(const char* server_name,
106 uint16_t server_port,
107 PP_CompletionCallback callback) {
108 if (!server_name)
109 return PP_ERROR_BADARGUMENT;
110 if (!callback.func)
111 return PP_ERROR_BLOCKS_MAIN_THREAD;
112
113 if (connection_state_ != CONNECTED)
114 return PP_ERROR_FAILED;
115 if (ssl_handshake_callback_.func || read_callback_.func ||
116 write_callback_.func)
117 return PP_ERROR_INPROGRESS;
118
119 ssl_handshake_callback_ = callback;
120
121 // Send the request, the browser will call us back via SSLHandshakeACK.
122 SendSSLHandshake(server_name, server_port);
123 return PP_OK_COMPLETIONPENDING;
124 }
125
126 int32_t TCPSocketPrivateImpl::Read(char* buffer,
127 int32_t bytes_to_read,
128 PP_CompletionCallback callback) {
129 if (!buffer || bytes_to_read <= 0)
130 return PP_ERROR_BADARGUMENT;
131 if (!callback.func)
132 return PP_ERROR_BLOCKS_MAIN_THREAD;
133
134 if (!IsConnected())
135 return PP_ERROR_FAILED;
136 if (read_callback_.func || ssl_handshake_callback_.func)
137 return PP_ERROR_INPROGRESS;
138 // TODO(dmichael): use some other strategy for determining if an
139 // operation is in progress
140 read_buffer_ = buffer;
141 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize);
142 read_callback_ = callback;
143
144 // Send the request, the browser will call us back via ReadACK.
145 SendRead(bytes_to_read_);
146 return PP_OK_COMPLETIONPENDING;
147 }
148
149 int32_t TCPSocketPrivateImpl::Write(const char* buffer,
150 int32_t bytes_to_write,
151 PP_CompletionCallback callback) {
152 if (!buffer || bytes_to_write <= 0)
153 return PP_ERROR_BADARGUMENT;
154 if (!callback.func)
155 return PP_ERROR_BLOCKS_MAIN_THREAD;
156
157 if (!IsConnected())
158 return PP_ERROR_FAILED;
159 if (write_callback_.func || ssl_handshake_callback_.func)
160 return PP_ERROR_INPROGRESS;
161
162 if (bytes_to_write > kMaxWriteSize)
163 bytes_to_write = kMaxWriteSize;
164
165 write_callback_ = callback;
166
167 // Send the request, the browser will call us back via WriteACK.
168 SendWrite(std::string(buffer, bytes_to_write));
169 return PP_OK_COMPLETIONPENDING;
170 }
171
172 void TCPSocketPrivateImpl::Disconnect() {
173 if (connection_state_ == DISCONNECTED)
174 return;
175
176 connection_state_ = DISCONNECTED;
177
178 SendDisconnect();
179 socket_id_ = 0;
180
181 PostAbortAndClearIfNecessary(&connect_callback_);
182 PostAbortAndClearIfNecessary(&ssl_handshake_callback_);
183 PostAbortAndClearIfNecessary(&read_callback_);
184 PostAbortAndClearIfNecessary(&write_callback_);
185 read_buffer_ = NULL;
186 bytes_to_read_ = -1;
187 }
188
189 void TCPSocketPrivateImpl::OnConnectCompleted(
190 bool succeeded,
191 const PP_NetAddress_Private& local_addr,
192 const PP_NetAddress_Private& remote_addr) {
193 if (connection_state_ != BEFORE_CONNECT || !connect_callback_.func) {
194 NOTREACHED();
195 return;
196 }
197
198 if (succeeded) {
199 local_addr_ = local_addr;
200 remote_addr_ = remote_addr;
201 connection_state_ = CONNECTED;
202 }
203 PP_RunAndClearCompletionCallback(&connect_callback_,
204 succeeded ? PP_OK : PP_ERROR_FAILED);
205 }
206
207 void TCPSocketPrivateImpl::OnSSLHandshakeCompleted(bool succeeded) {
208 if (connection_state_ != CONNECTED || !ssl_handshake_callback_.func) {
209 NOTREACHED();
210 return;
211 }
212
213 if (succeeded) {
214 connection_state_ = SSL_CONNECTED;
215 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_OK);
216 } else {
217 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_ERROR_FAILED);
218 Disconnect();
219 }
220 }
221
222 void TCPSocketPrivateImpl::OnReadCompleted(bool succeeded,
223 const std::string& data) {
224 if (!read_callback_.func || !read_buffer_) {
225 NOTREACHED();
226 return;
227 }
228
229 if (succeeded) {
230 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
231 if (!data.empty())
232 memcpy(read_buffer_, data.c_str(), data.size());
233 }
234 read_buffer_ = NULL;
235 bytes_to_read_ = -1;
236
237 PP_RunAndClearCompletionCallback(
238 &read_callback_,
239 succeeded ? static_cast<int32_t>(data.size()) :
240 static_cast<int32_t>(PP_ERROR_FAILED));
241 }
242
243 void TCPSocketPrivateImpl::OnWriteCompleted(bool succeeded,
244 int32_t bytes_written) {
245 if (!write_callback_.func || (succeeded && bytes_written < 0)) {
246 NOTREACHED();
247 return;
248 }
249
250 PP_RunAndClearCompletionCallback(
251 &write_callback_,
252 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
253 }
254
255 void TCPSocketPrivateImpl::Init(uint32 socket_id) {
256 DCHECK(socket_id != 0);
257 socket_id_ = socket_id;
258 connection_state_ = BEFORE_CONNECT;
259 connect_callback_ = PP_BlockUntilComplete();
260 ssl_handshake_callback_ = PP_BlockUntilComplete();
261 read_callback_ = PP_BlockUntilComplete();
262 write_callback_ = PP_BlockUntilComplete();
263 read_buffer_ = NULL;
264 bytes_to_read_ = -1;
265
266 local_addr_.size = 0;
267 memset(local_addr_.data, 0,
268 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
269 remote_addr_.size = 0;
270 memset(remote_addr_.data, 0,
271 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
272 }
273
274 bool TCPSocketPrivateImpl::IsConnected() const {
275 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
276 }
277
278 void TCPSocketPrivateImpl::PostAbortAndClearIfNecessary(
279 PP_CompletionCallback* callback) {
280 DCHECK(callback);
281
282 if (callback->func) {
283 MessageLoop::current()->PostTask(FROM_HERE,
284 base::Bind(&AbortCallback, *callback));
285 *callback = PP_BlockUntilComplete();
286 }
287 }
288
289 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/shared_impl/private/tcp_socket_private_impl.h ('k') | ppapi/shared_impl/private/udp_socket_private_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698