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

Side by Side Diff: Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp

Issue 350763007: [WebSocket] Create Peer on the worker thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 m_bridge.clear(); 194 m_bridge.clear();
195 } 195 }
196 196
197 void WorkerThreadableWebSocketChannel::trace(Visitor* visitor) 197 void WorkerThreadableWebSocketChannel::trace(Visitor* visitor)
198 { 198 {
199 visitor->trace(m_bridge); 199 visitor->trace(m_bridge);
200 visitor->trace(m_workerClientWrapper); 200 visitor->trace(m_workerClientWrapper);
201 WebSocketChannel::trace(visitor); 201 WebSocketChannel::trace(visitor);
202 } 202 }
203 203
204 #if ENABLE(OILPAN) 204 Peer::Peer(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> clien tWrapper, WorkerLoaderProxy& loaderProxy, PassRefPtrWillBeRawPtr<ThreadableWebSo cketChannelSyncHelper> syncHelper)
205 Peer::Peer(RawPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, Worker LoaderProxy& loaderProxy, ExecutionContext* context, const String& sourceURL, un signed lineNumber, RawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper)
206 #else
207 Peer::Peer(PassRefPtr<WeakReference<Peer> > reference, PassRefPtr<ThreadableWebS ocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, Execut ionContext* context, const String& sourceURL, unsigned lineNumber, PassRefPtr<Th readableWebSocketChannelSyncHelper> syncHelper)
208 #endif
209 : m_workerClientWrapper(clientWrapper) 205 : m_workerClientWrapper(clientWrapper)
210 , m_loaderProxy(loaderProxy) 206 , m_loaderProxy(loaderProxy)
211 , m_mainWebSocketChannel(nullptr) 207 , m_mainWebSocketChannel(nullptr)
212 , m_syncHelper(syncHelper) 208 , m_syncHelper(syncHelper)
213 #if ENABLE(OILPAN) 209 {
214 , m_keepAlive(this) 210 ASSERT(!isMainThread());
215 #else 211 }
216 , m_weakFactory(reference, this) 212
217 #endif 213 Peer::~Peer()
214 {
215 ASSERT(!isMainThread());
216 }
217
218 PassOwnPtrWillBeRawPtr<Peer> Peer::create(PassRefPtrWillBeRawPtr<ThreadableWebSo cketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, PassRef PtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper)
219 {
220 return adoptPtrWillBeNoop(new Peer(clientWrapper, loaderProxy, syncHelper));
221 }
222
223 void Peer::initializeInternal(ExecutionContext* context, const String& sourceURL , unsigned lineNumber)
218 { 224 {
219 ASSERT(isMainThread()); 225 ASSERT(isMainThread());
220 ASSERT(m_workerClientWrapper.get());
221
222 Document* document = toDocument(context); 226 Document* document = toDocument(context);
223 if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) { 227 if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) {
224 m_mainWebSocketChannel = NewWebSocketChannelImpl::create(document, this, sourceURL, lineNumber); 228 m_mainWebSocketChannel = NewWebSocketChannelImpl::create(document, this, sourceURL, lineNumber);
225 } else { 229 } else {
226 m_mainWebSocketChannel = MainThreadWebSocketChannel::create(document, th is, sourceURL, lineNumber); 230 m_mainWebSocketChannel = MainThreadWebSocketChannel::create(document, th is, sourceURL, lineNumber);
227 } 231 }
228 }
229
230 Peer::~Peer()
231 {
232 ASSERT(isMainThread());
233 }
234
235 #if ENABLE(OILPAN)
236 void Peer::initialize(ExecutionContext* context, WeakMember<Peer>* reference, Wo rkerLoaderProxy* loaderProxy, RawPtr<ThreadableWebSocketChannelClientWrapper> cl ientWrapper, const String& sourceURLAtConnection, unsigned lineNumberAtConnectio n, RawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper)
237 {
238 // The caller must call destroy() to free the peer.
239 *reference = new Peer(clientWrapper, *loaderProxy, context, sourceURLAtConne ction, lineNumberAtConnection, syncHelper);
240 syncHelper->signalWorkerThread();
241 }
242 #else
243 void Peer::initialize(ExecutionContext* context, PassRefPtr<WeakReference<Peer> > reference, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChann elClientWrapper> clientWrapper, const String& sourceURLAtConnection, unsigned li neNumberAtConnection, PassRefPtr<ThreadableWebSocketChannelSyncHelper> prpSyncHe lper)
244 {
245 RefPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = prpSyncHelper;
246 // The caller must call destroy() to free the peer.
247 new Peer(reference, clientWrapper, *loaderProxy, context, sourceURLAtConnect ion, lineNumberAtConnection, syncHelper);
248 syncHelper->signalWorkerThread();
249 }
250 #endif
251
252 void Peer::destroy()
253 {
254 ASSERT(isMainThread());
255 disconnect();
256
257 #if ENABLE(OILPAN)
258 m_keepAlive = nullptr;
259 m_syncHelper->signalWorkerThread(); 232 m_syncHelper->signalWorkerThread();
260 m_syncHelper = nullptr;
261 #else
262 delete this;
263 #endif
264 } 233 }
265 234
266 void Peer::connect(const KURL& url, const String& protocol) 235 void Peer::connect(const KURL& url, const String& protocol)
267 { 236 {
268 ASSERT(isMainThread()); 237 ASSERT(isMainThread());
269 ASSERT(m_syncHelper); 238 ASSERT(m_syncHelper);
270 if (!m_mainWebSocketChannel) { 239 if (!m_mainWebSocketChannel) {
271 m_syncHelper->setConnectRequestResult(false); 240 m_syncHelper->setConnectRequestResult(false);
272 } else { 241 } else {
273 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco l); 242 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco l);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 ASSERT(m_syncHelper); 299 ASSERT(m_syncHelper);
331 if (!m_mainWebSocketChannel) 300 if (!m_mainWebSocketChannel)
332 return; 301 return;
333 m_mainWebSocketChannel->fail(reason, level, sourceURL, lineNumber); 302 m_mainWebSocketChannel->fail(reason, level, sourceURL, lineNumber);
334 } 303 }
335 304
336 void Peer::disconnect() 305 void Peer::disconnect()
337 { 306 {
338 ASSERT(isMainThread()); 307 ASSERT(isMainThread());
339 ASSERT(m_syncHelper); 308 ASSERT(m_syncHelper);
340 if (!m_mainWebSocketChannel) 309 if (m_mainWebSocketChannel) {
341 return; 310 m_mainWebSocketChannel->disconnect();
342 m_mainWebSocketChannel->disconnect(); 311 m_mainWebSocketChannel = nullptr;
343 m_mainWebSocketChannel = nullptr; 312 }
313 m_syncHelper->signalWorkerThread();
344 } 314 }
345 315
346 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St ring& subprotocol, const String& extensions) 316 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St ring& subprotocol, const String& extensions)
347 { 317 {
348 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 318 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
349 workerClientWrapper->didConnect(subprotocol, extensions); 319 workerClientWrapper->didConnect(subprotocol, extensions);
350 } 320 }
351 321
352 void Peer::didConnect(const String& subprotocol, const String& extensions) 322 void Peer::didConnect(const String& subprotocol, const String& extensions)
353 { 323 {
354 ASSERT(isMainThread()); 324 ASSERT(isMainThread());
355 // It is important to seprate task creation from posting 325 // It is important to seprate task creation from posting
356 // the task. See the above comment. 326 // the task. See the above comment.
357 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidConnect, m_workerClientWrapper.get(), subprotocol, extensions); 327 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidConnect, m_workerClientWrapper, subprotocol, extensions);
358 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 328 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
359 } 329 }
360 330
361 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c onst String& message) 331 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c onst String& message)
362 { 332 {
363 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 333 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
364 workerClientWrapper->didReceiveMessage(message); 334 workerClientWrapper->didReceiveMessage(message);
365 } 335 }
366 336
367 void Peer::didReceiveMessage(const String& message) 337 void Peer::didReceiveMessage(const String& message)
368 { 338 {
369 ASSERT(isMainThread()); 339 ASSERT(isMainThread());
370 // It is important to seprate task creation from posting 340 // It is important to seprate task creation from posting
371 // the task. See the above comment. 341 // the task. See the above comment.
372 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveMessage, m_workerClientWrapper.get(), message); 342 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveMessage, m_workerClientWrapper, message);
373 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 343 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
374 } 344 }
375 345
376 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper , PassOwnPtr<Vector<char> > binaryData) 346 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper , PassOwnPtr<Vector<char> > binaryData)
377 { 347 {
378 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 348 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
379 workerClientWrapper->didReceiveBinaryData(binaryData); 349 workerClientWrapper->didReceiveBinaryData(binaryData);
380 } 350 }
381 351
382 void Peer::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData) 352 void Peer::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData)
383 { 353 {
384 ASSERT(isMainThread()); 354 ASSERT(isMainThread());
385 // It is important to seprate task creation from posting 355 // It is important to seprate task creation from posting
386 // the task. See the above comment. 356 // the task. See the above comment.
387 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveBinaryData, m_workerClientWrapper.get(), binaryData); 357 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveBinaryData, m_workerClientWrapper, binaryData);
388 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 358 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
389 } 359 }
390 360
391 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper, unsigned long consumed) 361 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper, unsigned long consumed)
392 { 362 {
393 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 363 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
394 workerClientWrapper->didConsumeBufferedAmount(consumed); 364 workerClientWrapper->didConsumeBufferedAmount(consumed);
395 } 365 }
396 366
397 void Peer::didConsumeBufferedAmount(unsigned long consumed) 367 void Peer::didConsumeBufferedAmount(unsigned long consumed)
398 { 368 {
399 ASSERT(isMainThread()); 369 ASSERT(isMainThread());
400 // It is important to seprate task creation from posting 370 // It is important to seprate task creation from posting
401 // the task. See the above comment. 371 // the task. See the above comment.
402 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidConsumeBufferedAmount, m_workerClientWrapper.get(), consumed); 372 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidConsumeBufferedAmount, m_workerClientWrapper, consumed);
403 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 373 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
404 } 374 }
405 375
406 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper) 376 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper)
407 { 377 {
408 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 378 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
409 workerClientWrapper->didStartClosingHandshake(); 379 workerClientWrapper->didStartClosingHandshake();
410 } 380 }
411 381
412 void Peer::didStartClosingHandshake() 382 void Peer::didStartClosingHandshake()
413 { 383 {
414 ASSERT(isMainThread()); 384 ASSERT(isMainThread());
415 // It is important to seprate task creation from posting 385 // It is important to seprate task creation from posting
416 // the task. See the above comment. 386 // the task. See the above comment.
417 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidStartClosingHandshake, m_workerClientWrapper.get()); 387 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidStartClosingHandshake, m_workerClientWrapper);
418 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 388 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
419 } 389 }
420 390
421 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig ned short code, const String& reason) 391 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig ned short code, const String& reason)
422 { 392 {
423 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 393 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
424 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason); 394 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason);
425 } 395 }
426 396
427 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) 397 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
428 { 398 {
429 ASSERT(isMainThread()); 399 ASSERT(isMainThread());
430 m_mainWebSocketChannel = nullptr; 400 m_mainWebSocketChannel = nullptr;
431 // It is important to seprate task creation from posting 401 // It is important to seprate task creation from posting
432 // the task. See the above comment. 402 // the task. See the above comment.
433 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidClose, m_workerClientWrapper.get(), closingHandshakeCompletion, code, reason) ; 403 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidClose, m_workerClientWrapper, closingHandshakeCompletion, code, reason);
434 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 404 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
435 } 405 }
436 406
437 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp er) 407 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp er)
438 { 408 {
439 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 409 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
440 workerClientWrapper->didReceiveMessageError(); 410 workerClientWrapper->didReceiveMessageError();
441 } 411 }
442 412
443 void Peer::didReceiveMessageError() 413 void Peer::didReceiveMessageError()
444 { 414 {
445 ASSERT(isMainThread()); 415 ASSERT(isMainThread());
446 // It is important to seprate task creation from posting 416 // It is important to seprate task creation from posting
447 // the task. See the above comment. 417 // the task. See the above comment.
448 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveMessageError, m_workerClientWrapper.get()); 418 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&workerGlobalScope DidReceiveMessageError, m_workerClientWrapper);
449 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); 419 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
450 } 420 }
451 421
452 void Peer::trace(Visitor* visitor) 422 void Peer::trace(Visitor* visitor)
453 { 423 {
454 visitor->trace(m_workerClientWrapper); 424 visitor->trace(m_workerClientWrapper);
455 visitor->trace(m_mainWebSocketChannel); 425 visitor->trace(m_mainWebSocketChannel);
456 visitor->trace(m_syncHelper); 426 visitor->trace(m_syncHelper);
457 WebSocketChannelClient::trace(visitor); 427 WebSocketChannelClient::trace(visitor);
458 } 428 }
459 429
460 Bridge::Bridge(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> w orkerClientWrapper, WorkerGlobalScope& workerGlobalScope) 430 Bridge::Bridge(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> w orkerClientWrapper, WorkerGlobalScope& workerGlobalScope)
461 : m_workerClientWrapper(workerClientWrapper) 431 : m_workerClientWrapper(workerClientWrapper)
462 , m_workerGlobalScope(workerGlobalScope) 432 , m_workerGlobalScope(workerGlobalScope)
463 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) 433 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy())
464 , m_syncHelper(nullptr) 434 , m_syncHelper(nullptr)
465 , m_peer(nullptr) 435 , m_peer(Peer::create(m_workerClientWrapper, m_loaderProxy, m_syncHelper))
466 { 436 {
467 ASSERT(m_workerClientWrapper.get()); 437 ASSERT(m_workerClientWrapper.get());
468 } 438 }
469 439
470 Bridge::~Bridge() 440 Bridge::~Bridge()
471 { 441 {
472 ASSERT(hasTerminatedPeer()); 442 ASSERT(!hasPeer());
473 } 443 }
474 444
475 void Bridge::initialize(const String& sourceURL, unsigned lineNumber) 445 void Bridge::initialize(const String& sourceURL, unsigned lineNumber)
476 { 446 {
477 #if !ENABLE(OILPAN)
478 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( );
479 m_peer = WeakPtr<Peer>(reference);
480 #endif
481
482 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent())); 447 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent()));
483 // This pointer is guaranteed to be valid until we call terminatePeer. 448 // This pointer is guaranteed to be valid until we call terminatePeer.
484 m_syncHelper = syncHelper.get(); 449 m_syncHelper = syncHelper.get();
485 450
486 RefPtrWillBeRawPtr<Bridge> protect(this); 451 RefPtrWillBeRawPtr<Bridge> protect(this);
487 #if ENABLE(OILPAN)
488 // In order to assure all temporary objects to be destroyed before 452 // In order to assure all temporary objects to be destroyed before
489 // posting the task, we separate task creation and posting. 453 // posting the task, we separate task creation and posting.
490 // In other words, it is dangerous to have a complicated expression 454 // In other words, it is dangerous to have a complicated expression
491 // as a waitForMethodCompletion argument. 455 // as a waitForMethodCompletion argument.
492 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize, &m_peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), s ourceURL, lineNumber, syncHelper.get()); 456 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize, AllowCrossThreadAccess(m_peer.get()), sourceURL, lineNumber);
493 #else
494 // See the above comment.
495 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&Peer::initialize, reference, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL, lineNumber, syncHelper.get());
496 #endif
497 if (!waitForMethodCompletion(task.release())) { 457 if (!waitForMethodCompletion(task.release())) {
498 // The worker thread has been signalled to shutdown before method comple tion. 458 // The worker thread has been signalled to shutdown before method comple tion.
499 disconnect(); 459 disconnect();
500 } 460 }
501 } 461 }
502 462
503 bool Bridge::connect(const KURL& url, const String& protocol) 463 bool Bridge::connect(const KURL& url, const String& protocol)
504 { 464 {
505 if (hasTerminatedPeer()) 465 if (!hasPeer())
506 return false; 466 return false;
507 467
508 RefPtrWillBeRawPtr<Bridge> protect(this); 468 RefPtrWillBeRawPtr<Bridge> protect(this);
509 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer, u rl, protocol))) 469 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer.ge t(), url, protocol)))
510 return false; 470 return false;
511 471
512 return m_syncHelper->connectRequestResult(); 472 return m_syncHelper->connectRequestResult();
513 } 473 }
514 474
515 WebSocketChannel::SendResult Bridge::send(const String& message) 475 WebSocketChannel::SendResult Bridge::send(const String& message)
516 { 476 {
517 if (hasTerminatedPeer()) 477 if (!hasPeer())
518 return WebSocketChannel::SendFail; 478 return WebSocketChannel::SendFail;
519 479
520 RefPtrWillBeRawPtr<Bridge> protect(this); 480 RefPtrWillBeRawPtr<Bridge> protect(this);
521 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::send, m_peer, mess age))) 481 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::send, m_peer.get() , message)))
522 return WebSocketChannel::SendFail; 482 return WebSocketChannel::SendFail;
523 483
524 return m_syncHelper->sendRequestResult(); 484 return m_syncHelper->sendRequestResult();
525 } 485 }
526 486
527 WebSocketChannel::SendResult Bridge::send(const ArrayBuffer& binaryData, unsigne d byteOffset, unsigned byteLength) 487 WebSocketChannel::SendResult Bridge::send(const ArrayBuffer& binaryData, unsigne d byteOffset, unsigned byteLength)
528 { 488 {
529 if (hasTerminatedPeer()) 489 if (!hasPeer())
530 return WebSocketChannel::SendFail; 490 return WebSocketChannel::SendFail;
531 491
532 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. 492 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
533 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); 493 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength));
534 if (binaryData.byteLength()) 494 if (binaryData.byteLength())
535 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); 495 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength);
536 496
537 RefPtrWillBeRawPtr<Bridge> protect(this); 497 RefPtrWillBeRawPtr<Bridge> protect(this);
538 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendArrayBuffer, m _peer, data.release()))) 498 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendArrayBuffer, m _peer.get(), data.release())))
539 return WebSocketChannel::SendFail; 499 return WebSocketChannel::SendFail;
540 500
541 return m_syncHelper->sendRequestResult(); 501 return m_syncHelper->sendRequestResult();
542 } 502 }
543 503
544 WebSocketChannel::SendResult Bridge::send(PassRefPtr<BlobDataHandle> data) 504 WebSocketChannel::SendResult Bridge::send(PassRefPtr<BlobDataHandle> data)
545 { 505 {
546 if (hasTerminatedPeer()) 506 if (!hasPeer())
547 return WebSocketChannel::SendFail; 507 return WebSocketChannel::SendFail;
548 508
549 RefPtrWillBeRawPtr<Bridge> protect(this); 509 RefPtrWillBeRawPtr<Bridge> protect(this);
550 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendBlob, m_peer, data))) 510 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::sendBlob, m_peer.g et(), data)))
551 return WebSocketChannel::SendFail; 511 return WebSocketChannel::SendFail;
552 512
553 return m_syncHelper->sendRequestResult(); 513 return m_syncHelper->sendRequestResult();
554 } 514 }
555 515
556 void Bridge::close(int code, const String& reason) 516 void Bridge::close(int code, const String& reason)
557 { 517 {
558 if (hasTerminatedPeer()) 518 if (!hasPeer())
559 return; 519 return;
560 520
561 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::close, m_peer, c ode, reason)); 521 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::close, m_peer.ge t(), code, reason));
562 } 522 }
563 523
564 void Bridge::fail(const String& reason, MessageLevel level, const String& source URL, unsigned lineNumber) 524 void Bridge::fail(const String& reason, MessageLevel level, const String& source URL, unsigned lineNumber)
565 { 525 {
566 if (hasTerminatedPeer()) 526 if (!hasPeer())
567 return; 527 return;
568 528
569 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::fail, m_peer, re ason, level, sourceURL, lineNumber)); 529 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::fail, m_peer.get (), reason, level, sourceURL, lineNumber));
570 } 530 }
571 531
572 void Bridge::disconnect() 532 void Bridge::disconnect()
573 { 533 {
574 if (hasTerminatedPeer()) 534 if (!hasPeer())
575 return; 535 return;
576 536
577 clearClientWrapper(); 537 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, m_peer.get( )));
578 terminatePeer(); 538 // Here |m_peer| is detached from the main thread and we can delete it.
579 }
580 539
581 void Bridge::clearClientWrapper() 540 m_peer = nullptr;
582 { 541 m_syncHelper = nullptr;
583 m_workerClientWrapper->clearClient(); 542 // We won't use this any more.
543 m_workerGlobalScope.clear();
584 } 544 }
585 545
586 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end, 546 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end,
587 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. 547 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference.
588 bool Bridge::waitForMethodCompletion(PassOwnPtr<ExecutionContextTask> task) 548 bool Bridge::waitForMethodCompletion(PassOwnPtr<ExecutionContextTask> task)
589 { 549 {
590 ASSERT(m_workerGlobalScope); 550 ASSERT(m_workerGlobalScope);
591 ASSERT(m_syncHelper); 551 ASSERT(m_syncHelper);
592 552
593 m_loaderProxy.postTaskToLoader(task); 553 m_loaderProxy.postTaskToLoader(task);
594 554
595 // We wait for the syncHelper event even if a shutdown event is fired. 555 // We wait for the syncHelper event even if a shutdown event is fired.
596 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w ait this. 556 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w ait this.
597 Vector<blink::WebWaitableEvent*> events; 557 Vector<blink::WebWaitableEvent*> events;
598 events.append(m_syncHelper->event()); 558 events.append(m_syncHelper->event());
599 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); 559 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
600 blink::Platform::current()->waitMultipleEvents(events); 560 blink::Platform::current()->waitMultipleEvents(events);
601 // This is checking whether a shutdown event is fired or not. 561 // This is checking whether a shutdown event is fired or not.
602 return !m_workerGlobalScope->thread()->terminated(); 562 return !m_workerGlobalScope->thread()->terminated();
603 } 563 }
604 564
605 void Bridge::terminatePeer()
606 {
607 ASSERT(!hasTerminatedPeer());
608
609 #if ENABLE(OILPAN)
610 // The worker thread has to wait for the main thread to complete Peer::destr oy,
611 // because the worker thread has to make sure that the main thread does not have any
612 // references to on-heap objects allocated in the thread heap of the worker thread
613 // before the worker thread shuts down.
614 waitForMethodCompletion(createCrossThreadTask(&Peer::destroy, m_peer));
615 #else
616 m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::destroy, m_peer) );
617 #endif
618
619 // Peer::destroy() deletes m_peer and then m_syncHelper will be released.
620 // We must not touch m_syncHelper any more.
621 m_syncHelper = nullptr;
622
623 // We won't use this any more.
624 m_workerGlobalScope = nullptr;
625 }
626
627 void Bridge::trace(Visitor* visitor) 565 void Bridge::trace(Visitor* visitor)
628 { 566 {
629 visitor->trace(m_workerClientWrapper); 567 visitor->trace(m_workerClientWrapper);
630 visitor->trace(m_workerGlobalScope); 568 visitor->trace(m_workerGlobalScope);
631 visitor->trace(m_syncHelper); 569 visitor->trace(m_syncHelper);
632 visitor->trace(m_peer); 570 visitor->trace(m_peer);
633 } 571 }
634 572
635 } // namespace blink 573 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698