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

Side by Side Diff: webkit/plugins/ppapi/ppb_websocket_impl.cc

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: export AssertLockHeld Created 8 years, 6 months 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
« no previous file with comments | « webkit/plugins/ppapi/ppb_websocket_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "webkit/plugins/ppapi/ppb_websocket_impl.h" 5 #include "webkit/plugins/ppapi/ppb_websocket_impl.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 return ws->GetReference(); 100 return ws->GetReference();
101 } 101 }
102 102
103 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() { 103 PPB_WebSocket_API* PPB_WebSocket_Impl::AsPPB_WebSocket_API() {
104 return this; 104 return this;
105 } 105 }
106 106
107 int32_t PPB_WebSocket_Impl::Connect(PP_Var url, 107 int32_t PPB_WebSocket_Impl::Connect(PP_Var url,
108 const PP_Var protocols[], 108 const PP_Var protocols[],
109 uint32_t protocol_count, 109 uint32_t protocol_count,
110 PP_CompletionCallback callback) { 110 scoped_refptr<TrackedCallback> callback) {
111 // Check mandatory interfaces. 111 // Check mandatory interfaces.
112 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this); 112 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this);
113 DCHECK(plugin_instance); 113 DCHECK(plugin_instance);
114 if (!plugin_instance) 114 if (!plugin_instance)
115 return PP_ERROR_FAILED; 115 return PP_ERROR_FAILED;
116 116
117 // Connect() can be called at most once. 117 // Connect() can be called at most once.
118 if (websocket_.get()) 118 if (websocket_.get())
119 return PP_ERROR_INPROGRESS; 119 return PP_ERROR_INPROGRESS;
120 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID) 120 if (state_ != PP_WEBSOCKETREADYSTATE_INVALID)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 character == '{' || character == '}') 174 character == '{' || character == '}')
175 return PP_ERROR_BADARGUMENT; 175 return PP_ERROR_BADARGUMENT;
176 } 176 }
177 // Join protocols with the comma separator. 177 // Join protocols with the comma separator.
178 if (i != 0) 178 if (i != 0)
179 protocol_string.append(","); 179 protocol_string.append(",");
180 protocol_string.append(protocol->value()); 180 protocol_string.append(protocol->value());
181 } 181 }
182 WebString web_protocols = WebString::fromUTF8(protocol_string); 182 WebString web_protocols = WebString::fromUTF8(protocol_string);
183 183
184 // Validate |callback| (Doesn't support blocking callback)
185 if (!callback.func)
186 return PP_ERROR_BLOCKS_MAIN_THREAD;
187
188 // Create WebKit::WebSocket object and connect. 184 // Create WebKit::WebSocket object and connect.
189 WebDocument document = plugin_instance->container()->element().document(); 185 WebDocument document = plugin_instance->container()->element().document();
190 websocket_.reset(WebSocket::create(document, this)); 186 websocket_.reset(WebSocket::create(document, this));
191 DCHECK(websocket_.get()); 187 DCHECK(websocket_.get());
192 if (!websocket_.get()) 188 if (!websocket_.get())
193 return PP_ERROR_NOTSUPPORTED; 189 return PP_ERROR_NOTSUPPORTED;
194 190
195 // Set receiving binary object type. 191 // Set receiving binary object type.
196 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer); 192 websocket_->setBinaryType(WebSocket::BinaryTypeArrayBuffer);
197 193
198 websocket_->connect(web_url, web_protocols); 194 websocket_->connect(web_url, web_protocols);
199 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING; 195 state_ = PP_WEBSOCKETREADYSTATE_CONNECTING;
200 196
201 // Install callback. 197 // Install callback.
202 connect_callback_ = new TrackedCallback(this, callback); 198 connect_callback_ = callback;
203 199
204 return PP_OK_COMPLETIONPENDING; 200 return PP_OK_COMPLETIONPENDING;
205 } 201 }
206 202
207 int32_t PPB_WebSocket_Impl::Close(uint16_t code, 203 int32_t PPB_WebSocket_Impl::Close(uint16_t code,
208 PP_Var reason, 204 PP_Var reason,
209 PP_CompletionCallback callback) { 205 scoped_refptr<TrackedCallback> callback) {
210 // Check mandarory interfaces. 206 // Check mandarory interfaces.
211 if (!websocket_.get()) 207 if (!websocket_.get())
212 return PP_ERROR_FAILED; 208 return PP_ERROR_FAILED;
213 209
214 // Validate |code| and |reason|. 210 // Validate |code| and |reason|.
215 scoped_refptr<StringVar> reason_string; 211 scoped_refptr<StringVar> reason_string;
216 WebString web_reason; 212 WebString web_reason;
217 WebSocket::CloseEventCode event_code = 213 WebSocket::CloseEventCode event_code =
218 static_cast<WebSocket::CloseEventCode>(code); 214 static_cast<WebSocket::CloseEventCode>(code);
219 if (code == PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED) { 215 if (code == PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED) {
(...skipping 21 matching lines...) Expand all
241 web_reason = WebString::fromUTF8(reason_string->value()); 237 web_reason = WebString::fromUTF8(reason_string->value());
242 } 238 }
243 } 239 }
244 240
245 // Check state. 241 // Check state.
246 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING) 242 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING)
247 return PP_ERROR_INPROGRESS; 243 return PP_ERROR_INPROGRESS;
248 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) 244 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED)
249 return PP_OK; 245 return PP_OK;
250 246
251 // Validate |callback| (Doesn't support blocking callback)
252 if (!callback.func)
253 return PP_ERROR_BLOCKS_MAIN_THREAD;
254
255 // Install |callback|. 247 // Install |callback|.
256 close_callback_ = new TrackedCallback(this, callback); 248 close_callback_ = callback;
257 249
258 // Abort ongoing connect. 250 // Abort ongoing connect.
259 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { 251 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) {
260 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; 252 state_ = PP_WEBSOCKETREADYSTATE_CLOSING;
261 // Need to do a "Post" to avoid reentering the plugin. 253 // Need to do a "Post" to avoid reentering the plugin.
262 connect_callback_->PostAbort(); 254 connect_callback_->PostAbort();
263 connect_callback_ = NULL; 255 connect_callback_ = NULL;
264 websocket_->fail( 256 websocket_->fail(
265 "WebSocket was closed before the connection was established."); 257 "WebSocket was closed before the connection was established.");
266 return PP_OK_COMPLETIONPENDING; 258 return PP_OK_COMPLETIONPENDING;
267 } 259 }
268 260
269 // Abort ongoing receive. 261 // Abort ongoing receive.
270 if (wait_for_receive_) { 262 if (wait_for_receive_) {
271 wait_for_receive_ = false; 263 wait_for_receive_ = false;
272 receive_callback_var_ = NULL; 264 receive_callback_var_ = NULL;
273 265
274 // Need to do a "Post" to avoid reentering the plugin. 266 // Need to do a "Post" to avoid reentering the plugin.
275 receive_callback_->PostAbort(); 267 receive_callback_->PostAbort();
276 receive_callback_ = NULL; 268 receive_callback_ = NULL;
277 } 269 }
278 270
279 // Close connection. 271 // Close connection.
280 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; 272 state_ = PP_WEBSOCKETREADYSTATE_CLOSING;
281 websocket_->close(event_code, web_reason); 273 websocket_->close(event_code, web_reason);
282 274
283 return PP_OK_COMPLETIONPENDING; 275 return PP_OK_COMPLETIONPENDING;
284 } 276 }
285 277
286 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, 278 int32_t PPB_WebSocket_Impl::ReceiveMessage(
287 PP_CompletionCallback callback) { 279 PP_Var* message,
280 scoped_refptr<TrackedCallback> callback) {
288 // Check state. 281 // Check state.
289 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || 282 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID ||
290 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) 283 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING)
291 return PP_ERROR_BADARGUMENT; 284 return PP_ERROR_BADARGUMENT;
292 285
293 // Just return received message if any received message is queued. 286 // Just return received message if any received message is queued.
294 if (!received_messages_.empty()) { 287 if (!received_messages_.empty()) {
295 receive_callback_var_ = message; 288 receive_callback_var_ = message;
296 return DoReceive(); 289 return DoReceive();
297 } 290 }
298 291
299 // Check state again. In CLOSED state, no more messages will be received. 292 // Check state again. In CLOSED state, no more messages will be received.
300 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) 293 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED)
301 return PP_ERROR_BADARGUMENT; 294 return PP_ERROR_BADARGUMENT;
302 295
303 // Returns PP_ERROR_FAILED after an error is received and received messages 296 // Returns PP_ERROR_FAILED after an error is received and received messages
304 // is exhausted. 297 // is exhausted.
305 if (error_was_received_) 298 if (error_was_received_)
306 return PP_ERROR_FAILED; 299 return PP_ERROR_FAILED;
307 300
308 // Validate |callback| (Doesn't support blocking callback)
309 if (!callback.func)
310 return PP_ERROR_BLOCKS_MAIN_THREAD;
311
312 // Or retain |message| as buffer to store and install |callback|. 301 // Or retain |message| as buffer to store and install |callback|.
313 wait_for_receive_ = true; 302 wait_for_receive_ = true;
314 receive_callback_var_ = message; 303 receive_callback_var_ = message;
315 receive_callback_ = new TrackedCallback(this, callback); 304 receive_callback_ = callback;
316 305
317 return PP_OK_COMPLETIONPENDING; 306 return PP_OK_COMPLETIONPENDING;
318 } 307 }
319 308
320 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { 309 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) {
321 // Check mandatory interfaces. 310 // Check mandatory interfaces.
322 if (!websocket_.get()) 311 if (!websocket_.get())
323 return PP_ERROR_FAILED; 312 return PP_ERROR_FAILED;
324 313
325 // Check state. 314 // Check state.
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 525
537 *receive_callback_var_ = received_messages_.front()->GetPPVar(); 526 *receive_callback_var_ = received_messages_.front()->GetPPVar();
538 received_messages_.pop(); 527 received_messages_.pop();
539 receive_callback_var_ = NULL; 528 receive_callback_var_ = NULL;
540 wait_for_receive_ = false; 529 wait_for_receive_ = false;
541 return PP_OK; 530 return PP_OK;
542 } 531 }
543 532
544 } // namespace ppapi 533 } // namespace ppapi
545 } // namespace webkit 534 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppb_websocket_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698