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

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: try again Created 8 years, 7 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
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|. Need to cast |CloseEventCodeNotSpecified| which is -1 to 210 // Validate |code|. Need to cast |CloseEventCodeNotSpecified| which is -1 to
215 // uint16_t for the comparison to work. 211 // uint16_t for the comparison to work.
216 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) { 212 if (code != static_cast<uint16_t>(WebSocket::CloseEventCodeNotSpecified)) {
217 if (!(code == WebSocket::CloseEventCodeNormalClosure || 213 if (!(code == WebSocket::CloseEventCodeNormalClosure ||
218 (WebSocket::CloseEventCodeMinimumUserDefined <= code && 214 (WebSocket::CloseEventCodeMinimumUserDefined <= code &&
219 code <= WebSocket::CloseEventCodeMaximumUserDefined))) 215 code <= WebSocket::CloseEventCodeMaximumUserDefined)))
(...skipping 14 matching lines...) Expand all
234 return PP_ERROR_BADARGUMENT; 230 return PP_ERROR_BADARGUMENT;
235 web_reason = WebString::fromUTF8(reason_string->value()); 231 web_reason = WebString::fromUTF8(reason_string->value());
236 } 232 }
237 233
238 // Check state. 234 // Check state.
239 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING) 235 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING)
240 return PP_ERROR_INPROGRESS; 236 return PP_ERROR_INPROGRESS;
241 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) 237 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED)
242 return PP_OK; 238 return PP_OK;
243 239
244 // Validate |callback| (Doesn't support blocking callback)
245 if (!callback.func)
246 return PP_ERROR_BLOCKS_MAIN_THREAD;
247
248 // Install |callback|. 240 // Install |callback|.
249 close_callback_ = new TrackedCallback(this, callback); 241 close_callback_ = callback;
250 242
251 // Abort ongoing connect. 243 // Abort ongoing connect.
252 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) { 244 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) {
253 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; 245 state_ = PP_WEBSOCKETREADYSTATE_CLOSING;
254 // Need to do a "Post" to avoid reentering the plugin. 246 // Need to do a "Post" to avoid reentering the plugin.
255 connect_callback_->PostAbort(); 247 connect_callback_->PostAbort();
256 connect_callback_ = NULL; 248 connect_callback_ = NULL;
257 websocket_->fail( 249 websocket_->fail(
258 "WebSocket was closed before the connection was established."); 250 "WebSocket was closed before the connection was established.");
259 return PP_OK_COMPLETIONPENDING; 251 return PP_OK_COMPLETIONPENDING;
260 } 252 }
261 253
262 // Abort ongoing receive. 254 // Abort ongoing receive.
263 if (wait_for_receive_) { 255 if (wait_for_receive_) {
264 wait_for_receive_ = false; 256 wait_for_receive_ = false;
265 receive_callback_var_ = NULL; 257 receive_callback_var_ = NULL;
266 258
267 // Need to do a "Post" to avoid reentering the plugin. 259 // Need to do a "Post" to avoid reentering the plugin.
268 receive_callback_->PostAbort(); 260 receive_callback_->PostAbort();
269 receive_callback_ = NULL; 261 receive_callback_ = NULL;
270 } 262 }
271 263
272 // Close connection. 264 // Close connection.
273 state_ = PP_WEBSOCKETREADYSTATE_CLOSING; 265 state_ = PP_WEBSOCKETREADYSTATE_CLOSING;
274 websocket_->close(code, web_reason); 266 websocket_->close(code, web_reason);
275 267
276 return PP_OK_COMPLETIONPENDING; 268 return PP_OK_COMPLETIONPENDING;
277 } 269 }
278 270
279 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, 271 int32_t PPB_WebSocket_Impl::ReceiveMessage(
280 PP_CompletionCallback callback) { 272 PP_Var* message,
273 scoped_refptr<TrackedCallback> callback) {
281 // Check state. 274 // Check state.
282 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID || 275 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID ||
283 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING) 276 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING)
284 return PP_ERROR_BADARGUMENT; 277 return PP_ERROR_BADARGUMENT;
285 278
286 // Just return received message if any received message is queued. 279 // Just return received message if any received message is queued.
287 if (!received_messages_.empty()) { 280 if (!received_messages_.empty()) {
288 receive_callback_var_ = message; 281 receive_callback_var_ = message;
289 return DoReceive(); 282 return DoReceive();
290 } 283 }
291 284
292 // Check state again. In CLOSED state, no more messages will be received. 285 // Check state again. In CLOSED state, no more messages will be received.
293 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED) 286 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED)
294 return PP_ERROR_BADARGUMENT; 287 return PP_ERROR_BADARGUMENT;
295 288
296 // Returns PP_ERROR_FAILED after an error is received and received messages 289 // Returns PP_ERROR_FAILED after an error is received and received messages
297 // is exhausted. 290 // is exhausted.
298 if (error_was_received_) 291 if (error_was_received_)
299 return PP_ERROR_FAILED; 292 return PP_ERROR_FAILED;
300 293
301 // Validate |callback| (Doesn't support blocking callback)
302 if (!callback.func)
303 return PP_ERROR_BLOCKS_MAIN_THREAD;
304
305 // Or retain |message| as buffer to store and install |callback|. 294 // Or retain |message| as buffer to store and install |callback|.
306 wait_for_receive_ = true; 295 wait_for_receive_ = true;
307 receive_callback_var_ = message; 296 receive_callback_var_ = message;
308 receive_callback_ = new TrackedCallback(this, callback); 297 receive_callback_ = callback;
309 298
310 return PP_OK_COMPLETIONPENDING; 299 return PP_OK_COMPLETIONPENDING;
311 } 300 }
312 301
313 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { 302 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) {
314 // Check mandatory interfaces. 303 // Check mandatory interfaces.
315 if (!websocket_.get()) 304 if (!websocket_.get())
316 return PP_ERROR_FAILED; 305 return PP_ERROR_FAILED;
317 306
318 // Check state. 307 // Check state.
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 518
530 *receive_callback_var_ = received_messages_.front()->GetPPVar(); 519 *receive_callback_var_ = received_messages_.front()->GetPPVar();
531 received_messages_.pop(); 520 received_messages_.pop();
532 receive_callback_var_ = NULL; 521 receive_callback_var_ = NULL;
533 wait_for_receive_ = false; 522 wait_for_receive_ = false;
534 return PP_OK; 523 return PP_OK;
535 } 524 }
536 525
537 } // namespace ppapi 526 } // namespace ppapi
538 } // namespace webkit 527 } // namespace webkit
OLDNEW
« ppapi/thunk/ppb_graphics_2d_api.h ('K') | « 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