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

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

Issue 368453003: [WebSocket] Task creation should be separated from task posting. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@crash
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
« no previous file with comments | « no previous file | 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 /* 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 336
337 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St ring& subprotocol, const String& extensions) 337 static void workerGlobalScopeDidConnect(ExecutionContext* context, PassRefPtrWil lBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const St ring& subprotocol, const String& extensions)
338 { 338 {
339 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 339 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
340 workerClientWrapper->didConnect(subprotocol, extensions); 340 workerClientWrapper->didConnect(subprotocol, extensions);
341 } 341 }
342 342
343 void WorkerThreadableWebSocketChannel::Peer::didConnect(const String& subprotoco l, const String& extensions) 343 void WorkerThreadableWebSocketChannel::Peer::didConnect(const String& subprotoco l, const String& extensions)
344 { 344 {
345 ASSERT(isMainThread()); 345 ASSERT(isMainThread());
346 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidConnect, m_workerClientWrapper.get(), subprotocol, extensions)); 346 // It is important to seprate task creation from posting
347 // the task. See the above comment.
348 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid Connect, m_workerClientWrapper.get(), subprotocol, extensions);
349 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
347 } 350 }
348 351
349 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c onst String& message) 352 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe fPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, c onst String& message)
350 { 353 {
351 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 354 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
352 workerClientWrapper->didReceiveMessage(message); 355 workerClientWrapper->didReceiveMessage(message);
353 } 356 }
354 357
355 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& mes sage) 358 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& mes sage)
356 { 359 {
357 ASSERT(isMainThread()); 360 ASSERT(isMainThread());
358 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidReceiveMessage, m_workerClientWrapper.get(), message)); 361 // It is important to seprate task creation from posting
362 // the task. See the above comment.
363 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid ReceiveMessage, m_workerClientWrapper.get(), message);
364 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
359 } 365 }
360 366
361 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper , PassOwnPtr<Vector<char> > binaryData) 367 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas sRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper , PassOwnPtr<Vector<char> > binaryData)
362 { 368 {
363 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 369 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
364 workerClientWrapper->didReceiveBinaryData(binaryData); 370 workerClientWrapper->didReceiveBinaryData(binaryData);
365 } 371 }
366 372
367 void WorkerThreadableWebSocketChannel::Peer::didReceiveBinaryData(PassOwnPtr<Vec tor<char> > binaryData) 373 void WorkerThreadableWebSocketChannel::Peer::didReceiveBinaryData(PassOwnPtr<Vec tor<char> > binaryData)
368 { 374 {
369 ASSERT(isMainThread()); 375 ASSERT(isMainThread());
370 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidReceiveBinaryData, m_workerClientWrapper.get(), binaryData)); 376 // It is important to seprate task creation from posting
377 // the task. See the above comment.
378 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid ReceiveBinaryData, m_workerClientWrapper.get(), binaryData);
379 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
371 } 380 }
372 381
373 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper, unsigned long consumed) 382 static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper, unsigned long consumed)
374 { 383 {
375 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 384 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
376 workerClientWrapper->didConsumeBufferedAmount(consumed); 385 workerClientWrapper->didConsumeBufferedAmount(consumed);
377 } 386 }
378 387
379 void WorkerThreadableWebSocketChannel::Peer::didConsumeBufferedAmount(unsigned l ong consumed) 388 void WorkerThreadableWebSocketChannel::Peer::didConsumeBufferedAmount(unsigned l ong consumed)
380 { 389 {
381 ASSERT(isMainThread()); 390 ASSERT(isMainThread());
382 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidConsumeBufferedAmount, m_workerClientWrapper.get(), consumed)); 391 // It is important to seprate task creation from posting
392 // the task. See the above comment.
393 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid ConsumeBufferedAmount, m_workerClientWrapper.get(), consumed);
394 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
383 } 395 }
384 396
385 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper) 397 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWra pper)
386 { 398 {
387 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 399 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
388 workerClientWrapper->didStartClosingHandshake(); 400 workerClientWrapper->didStartClosingHandshake();
389 } 401 }
390 402
391 void WorkerThreadableWebSocketChannel::Peer::didStartClosingHandshake() 403 void WorkerThreadableWebSocketChannel::Peer::didStartClosingHandshake()
392 { 404 {
393 ASSERT(isMainThread()); 405 ASSERT(isMainThread());
394 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidStartClosingHandshake, m_workerClientWrapper.get())); 406 // It is important to seprate task creation from posting
407 // the task. See the above comment.
408 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid StartClosingHandshake, m_workerClientWrapper.get());
409 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
395 } 410 }
396 411
397 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig ned short code, const String& reason) 412 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtrWillB eRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WebSocketC hannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsig ned short code, const String& reason)
398 { 413 {
399 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 414 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
400 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason); 415 workerClientWrapper->didClose(closingHandshakeCompletion, code, reason);
401 } 416 }
402 417
403 void WorkerThreadableWebSocketChannel::Peer::didClose(ClosingHandshakeCompletion Status closingHandshakeCompletion, unsigned short code, const String& reason) 418 void WorkerThreadableWebSocketChannel::Peer::didClose(ClosingHandshakeCompletion Status closingHandshakeCompletion, unsigned short code, const String& reason)
404 { 419 {
405 ASSERT(isMainThread()); 420 ASSERT(isMainThread());
406 m_mainWebSocketChannel = nullptr; 421 m_mainWebSocketChannel = nullptr;
407 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidClose, m_workerClientWrapper.get(), closingHandshakeCompletion, code, reas on)); 422 // It is important to seprate task creation from posting
423 // the task. See the above comment.
424 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid Close, m_workerClientWrapper.get(), closingHandshakeCompletion, code, reason);
425 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
408 } 426 }
409 427
410 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp er) 428 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P assRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapp er)
411 { 429 {
412 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 430 ASSERT_UNUSED(context, context->isWorkerGlobalScope());
413 workerClientWrapper->didReceiveMessageError(); 431 workerClientWrapper->didReceiveMessageError();
414 } 432 }
415 433
416 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() 434 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError()
417 { 435 {
418 ASSERT(isMainThread()); 436 ASSERT(isMainThread());
419 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidReceiveMessageError, m_workerClientWrapper.get())); 437 // It is important to seprate task creation from posting
438 // the task. See the above comment.
439 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid ReceiveMessageError, m_workerClientWrapper.get());
440 m_loaderProxy.postTaskToWorkerGlobalScope(task.release());
420 } 441 }
421 442
422 void WorkerThreadableWebSocketChannel::Peer::trace(Visitor* visitor) 443 void WorkerThreadableWebSocketChannel::Peer::trace(Visitor* visitor)
423 { 444 {
424 visitor->trace(m_workerClientWrapper); 445 visitor->trace(m_workerClientWrapper);
425 visitor->trace(m_mainWebSocketChannel); 446 visitor->trace(m_mainWebSocketChannel);
426 visitor->trace(m_syncHelper); 447 visitor->trace(m_syncHelper);
427 WebSocketChannelClient::trace(visitor); 448 WebSocketChannelClient::trace(visitor);
428 } 449 }
429 450
(...skipping 18 matching lines...) Expand all
448 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( ); 469 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( );
449 m_peer = WeakPtr<Peer>(reference); 470 m_peer = WeakPtr<Peer>(reference);
450 #endif 471 #endif
451 472
452 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent())); 473 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent()));
453 // This pointer is guaranteed to be valid until we call terminatePeer. 474 // This pointer is guaranteed to be valid until we call terminatePeer.
454 m_syncHelper = syncHelper.get(); 475 m_syncHelper = syncHelper.get();
455 476
456 RefPtrWillBeRawPtr<Bridge> protect(this); 477 RefPtrWillBeRawPtr<Bridge> protect(this);
457 #if ENABLE(OILPAN) 478 #if ENABLE(OILPAN)
458 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, &m_peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL, lineNumber, syncHelper.get()))) { 479 // In order to assure all temporary objects to be destroyed before
480 // posting the task, we separate task creation and posting.
481 // In other words, it is dangerous to have a complicated expression
482 // as a waitForMethodCompletion argument.
483 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, &m _peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sour ceURL, lineNumber, syncHelper.get());
459 #else 484 #else
460 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, reference , AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL , lineNumber, syncHelper.get()))) { 485 // See the above comment.
486 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, re ference, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), so urceURL, lineNumber, syncHelper.get());
461 #endif 487 #endif
488 if (!waitForMethodCompletion(task.release())) {
462 // The worker thread has been signalled to shutdown before method comple tion. 489 // The worker thread has been signalled to shutdown before method comple tion.
463 disconnect(); 490 disconnect();
464 } 491 }
465 } 492 }
466 493
467 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) 494 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol)
468 { 495 {
469 if (hasTerminatedPeer()) 496 if (hasTerminatedPeer())
470 return false; 497 return false;
471 498
472 RefPtrWillBeRawPtr<Bridge> protect(this); 499 RefPtrWillBeRawPtr<Bridge> protect(this);
473 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::connect, m_ peer, url.copy(), protocol.isolatedCopy())))) 500 // It is important to seprate task creation from calling
501 // waitForMethodCompletion. See the above comment.
502 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::conn ect, m_peer, url.copy(), protocol.isolatedCopy()));
503 if (!waitForMethodCompletion(task.release()))
474 return false; 504 return false;
475 505
476 return m_syncHelper->connectRequestResult(); 506 return m_syncHelper->connectRequestResult();
477 } 507 }
478 508
479 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) 509 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message)
480 { 510 {
481 if (hasTerminatedPeer()) 511 if (hasTerminatedPeer())
482 return WebSocketChannel::SendFail; 512 return WebSocketChannel::SendFail;
483 513
484 RefPtrWillBeRawPtr<Bridge> protect(this); 514 RefPtrWillBeRawPtr<Bridge> protect(this);
485 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::send, m_pee r, message.isolatedCopy())))) 515 // It is important to seprate task creation from calling
516 // waitForMethodCompletion. See the above comment.
517 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send , m_peer, message.isolatedCopy()));
518 if (!waitForMethodCompletion(task.release()))
486 return WebSocketChannel::SendFail; 519 return WebSocketChannel::SendFail;
487 520
488 return m_syncHelper->sendRequestResult(); 521 return m_syncHelper->sendRequestResult();
489 } 522 }
490 523
491 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) 524 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength)
492 { 525 {
493 if (hasTerminatedPeer()) 526 if (hasTerminatedPeer())
494 return WebSocketChannel::SendFail; 527 return WebSocketChannel::SendFail;
495 528
496 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. 529 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
497 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); 530 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength));
498 if (binaryData.byteLength()) 531 if (binaryData.byteLength())
499 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); 532 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength);
500 533
501 RefPtrWillBeRawPtr<Bridge> protect(this); 534 RefPtrWillBeRawPtr<Bridge> protect(this);
502 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendArrayBu ffer, m_peer, data.release())))) 535 // It is important to seprate task creation from calling
536 // waitForMethodCompletion. See the above comment.
537 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send ArrayBuffer, m_peer, data.release()));
538 if (!waitForMethodCompletion(task.release()))
503 return WebSocketChannel::SendFail; 539 return WebSocketChannel::SendFail;
504 540
505 return m_syncHelper->sendRequestResult(); 541 return m_syncHelper->sendRequestResult();
506 } 542 }
507 543
508 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) 544 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data)
509 { 545 {
510 if (hasTerminatedPeer()) 546 if (hasTerminatedPeer())
511 return WebSocketChannel::SendFail; 547 return WebSocketChannel::SendFail;
512 548
513 RefPtrWillBeRawPtr<Bridge> protect(this); 549 RefPtrWillBeRawPtr<Bridge> protect(this);
514 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendBlob, m _peer, data)))) 550 // It is important to seprate task creation from calling
551 // waitForMethodCompletion. See the above comment.
552 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send Blob, m_peer, data));
553 if (!waitForMethodCompletion(task.release()))
515 return WebSocketChannel::SendFail; 554 return WebSocketChannel::SendFail;
516 555
517 return m_syncHelper->sendRequestResult(); 556 return m_syncHelper->sendRequestResult();
518 } 557 }
519 558
520 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) 559 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son)
521 { 560 {
522 if (hasTerminatedPeer()) 561 if (hasTerminatedPeer())
523 return; 562 return;
524 563
525 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); 564 // It is important to seprate task creation from calling
565 // waitForMethodCompletion. See the above comment.
566 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::clos e, m_peer, code, reason.isolatedCopy()));
567 m_loaderProxy.postTaskToLoader(task.release());
526 } 568 }
527 569
528 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) 570 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber)
529 { 571 {
530 if (hasTerminatedPeer()) 572 if (hasTerminatedPeer())
531 return; 573 return;
532 574
533 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); 575 // It is important to seprate task creation from calling
576 // waitForMethodCompletion. See the above comment.
577 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::fail , m_peer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber));
578 m_loaderProxy.postTaskToLoader(task.release());
534 } 579 }
535 580
536 void WorkerThreadableWebSocketChannel::Bridge::disconnect() 581 void WorkerThreadableWebSocketChannel::Bridge::disconnect()
537 { 582 {
538 if (hasTerminatedPeer()) 583 if (hasTerminatedPeer())
539 return; 584 return;
540 585
541 clearClientWrapper(); 586 clearClientWrapper();
542 terminatePeer(); 587 terminatePeer();
543 } 588 }
(...skipping 18 matching lines...) Expand all
562 events.append(m_syncHelper->event()); 607 events.append(m_syncHelper->event());
563 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); 608 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
564 blink::Platform::current()->waitMultipleEvents(events); 609 blink::Platform::current()->waitMultipleEvents(events);
565 // This is checking whether a shutdown event is fired or not. 610 // This is checking whether a shutdown event is fired or not.
566 return !m_workerGlobalScope->thread()->runLoop().terminated(); 611 return !m_workerGlobalScope->thread()->runLoop().terminated();
567 } 612 }
568 613
569 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() 614 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer()
570 { 615 {
571 ASSERT(!hasTerminatedPeer()); 616 ASSERT(!hasTerminatedPeer());
617
618 // It is important to seprate task creation from calling
619 // waitForMethodCompletion. See the above comment.
620 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::dest roy, m_peer));
572 #if ENABLE(OILPAN) 621 #if ENABLE(OILPAN)
573 // The worker thread has to wait for the main thread to complete Peer::destr oy, 622 // The worker thread has to wait for the main thread to complete Peer::destr oy,
574 // because the worker thread has to make sure that the main thread does not have any 623 // because the worker thread has to make sure that the main thread does not have any
575 // references to on-heap objects allocated in the thread heap of the worker thread 624 // references to on-heap objects allocated in the thread heap of the worker thread
576 // before the worker thread shuts down. 625 // before the worker thread shuts down.
577 waitForMethodCompletion(CallClosureTask::create(bind(&Peer::destroy, m_peer) )); 626 waitForMethodCompletion(task.release());
578 #else 627 #else
579 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); 628 m_loaderProxy.postTaskToLoader(task.release());
580 #endif 629 #endif
581 630
582 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. 631 // Peer::destroy() deletes m_peer and then m_syncHelper will be released.
583 // We must not touch m_syncHelper any more. 632 // We must not touch m_syncHelper any more.
584 m_syncHelper = nullptr; 633 m_syncHelper = nullptr;
585 634
586 // We won't use this any more. 635 // We won't use this any more.
587 m_workerGlobalScope = nullptr; 636 m_workerGlobalScope = nullptr;
588 } 637 }
589 638
590 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor) 639 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor)
591 { 640 {
592 visitor->trace(m_workerClientWrapper); 641 visitor->trace(m_workerClientWrapper);
593 visitor->trace(m_workerGlobalScope); 642 visitor->trace(m_workerGlobalScope);
594 visitor->trace(m_syncHelper); 643 visitor->trace(m_syncHelper);
595 visitor->trace(m_peer); 644 visitor->trace(m_peer);
596 } 645 }
597 646
598 } // namespace WebCore 647 } // namespace WebCore
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698