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

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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( ); 448 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( );
449 m_peer = WeakPtr<Peer>(reference); 449 m_peer = WeakPtr<Peer>(reference);
450 #endif 450 #endif
451 451
452 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent())); 452 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent()));
453 // This pointer is guaranteed to be valid until we call terminatePeer. 453 // This pointer is guaranteed to be valid until we call terminatePeer.
454 m_syncHelper = syncHelper.get(); 454 m_syncHelper = syncHelper.get();
455 455
456 RefPtrWillBeRawPtr<Bridge> protect(this); 456 RefPtrWillBeRawPtr<Bridge> protect(this);
457 #if ENABLE(OILPAN) 457 #if ENABLE(OILPAN)
458 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, &m_peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL, lineNumber, syncHelper.get()))) { 458 // In order to assure all temporally objects to be destroyed before
459 // posting the task, we should bind the task. In other words, it is
460 // dangerous to have a complicated expression as a waitForMethodCompletion
461 // argument.
462 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, &m _peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sour ceURL, lineNumber, syncHelper.get());
459 #else 463 #else
460 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, reference , AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL , lineNumber, syncHelper.get()))) { 464 // See the above comment.
465 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, re ference, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), so urceURL, lineNumber, syncHelper.get());
461 #endif 466 #endif
467 if (!waitForMethodCompletion(task.release())) {
462 // The worker thread has been signalled to shutdown before method comple tion. 468 // The worker thread has been signalled to shutdown before method comple tion.
463 disconnect(); 469 disconnect();
464 } 470 }
465 } 471 }
466 472
467 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) 473 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol)
468 { 474 {
469 if (hasTerminatedPeer()) 475 if (hasTerminatedPeer())
470 return false; 476 return false;
471 477
472 RefPtrWillBeRawPtr<Bridge> protect(this); 478 RefPtrWillBeRawPtr<Bridge> protect(this);
473 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::connect, m_ peer, url.copy(), protocol.isolatedCopy())))) 479 // It is important to seprate the task creation from the
480 // waitForMethodCompletion call. See the above comment.
481 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::conn ect, m_peer, url.copy(), protocol.isolatedCopy()));
482 if (!waitForMethodCompletion(task.release()))
474 return false; 483 return false;
475 484
476 return m_syncHelper->connectRequestResult(); 485 return m_syncHelper->connectRequestResult();
477 } 486 }
478 487
479 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) 488 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message)
480 { 489 {
481 if (hasTerminatedPeer()) 490 if (hasTerminatedPeer())
482 return WebSocketChannel::SendFail; 491 return WebSocketChannel::SendFail;
483 492
484 RefPtrWillBeRawPtr<Bridge> protect(this); 493 RefPtrWillBeRawPtr<Bridge> protect(this);
485 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::send, m_pee r, message.isolatedCopy())))) 494 // It is important to seprate the task creation from the
495 // waitForMethodCompletion call. See the above comment.
496 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send , m_peer, message.isolatedCopy()));
497 if (!waitForMethodCompletion(task.release()))
486 return WebSocketChannel::SendFail; 498 return WebSocketChannel::SendFail;
487 499
488 return m_syncHelper->sendRequestResult(); 500 return m_syncHelper->sendRequestResult();
489 } 501 }
490 502
491 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) 503 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength)
492 { 504 {
493 if (hasTerminatedPeer()) 505 if (hasTerminatedPeer())
494 return WebSocketChannel::SendFail; 506 return WebSocketChannel::SendFail;
495 507
496 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. 508 // 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)); 509 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength));
498 if (binaryData.byteLength()) 510 if (binaryData.byteLength())
499 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); 511 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength);
500 512
501 RefPtrWillBeRawPtr<Bridge> protect(this); 513 RefPtrWillBeRawPtr<Bridge> protect(this);
502 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendArrayBu ffer, m_peer, data.release())))) 514 // It is important to seprate the task creation from the
515 // waitForMethodCompletion call. See the above comment.
516 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send ArrayBuffer, m_peer, data.release()));
517 if (!waitForMethodCompletion(task.release()))
503 return WebSocketChannel::SendFail; 518 return WebSocketChannel::SendFail;
504 519
505 return m_syncHelper->sendRequestResult(); 520 return m_syncHelper->sendRequestResult();
506 } 521 }
507 522
508 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) 523 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data)
509 { 524 {
510 if (hasTerminatedPeer()) 525 if (hasTerminatedPeer())
511 return WebSocketChannel::SendFail; 526 return WebSocketChannel::SendFail;
512 527
513 RefPtrWillBeRawPtr<Bridge> protect(this); 528 RefPtrWillBeRawPtr<Bridge> protect(this);
514 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendBlob, m _peer, data)))) 529 // It is important to seprate the task creation from the
530 // waitForMethodCompletion call. See the above comment.
531 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send Blob, m_peer, data));
532 if (!waitForMethodCompletion(task.release()))
515 return WebSocketChannel::SendFail; 533 return WebSocketChannel::SendFail;
516 534
517 return m_syncHelper->sendRequestResult(); 535 return m_syncHelper->sendRequestResult();
518 } 536 }
519 537
520 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) 538 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son)
521 { 539 {
522 if (hasTerminatedPeer()) 540 if (hasTerminatedPeer())
523 return; 541 return;
524 542
525 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); 543 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy())));
hiroshige 2014/07/01 14:13:41 Should we modify this line as well? The temporary
yhirano 2014/07/02 01:35:23 Thanks, done.
526 } 544 }
527 545
528 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) 546 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber)
529 { 547 {
530 if (hasTerminatedPeer()) 548 if (hasTerminatedPeer())
531 return; 549 return;
532 550
533 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); 551 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber)));
hiroshige 2014/07/01 14:13:41 same as above.
yhirano 2014/07/02 01:35:23 Done.
534 } 552 }
535 553
536 void WorkerThreadableWebSocketChannel::Bridge::disconnect() 554 void WorkerThreadableWebSocketChannel::Bridge::disconnect()
537 { 555 {
538 if (hasTerminatedPeer()) 556 if (hasTerminatedPeer())
539 return; 557 return;
540 558
541 clearClientWrapper(); 559 clearClientWrapper();
542 terminatePeer(); 560 terminatePeer();
543 } 561 }
(...skipping 18 matching lines...) Expand all
562 events.append(m_syncHelper->event()); 580 events.append(m_syncHelper->event());
563 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); 581 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
564 blink::Platform::current()->waitMultipleEvents(events); 582 blink::Platform::current()->waitMultipleEvents(events);
565 // This is checking whether a shutdown event is fired or not. 583 // This is checking whether a shutdown event is fired or not.
566 return !m_workerGlobalScope->thread()->runLoop().terminated(); 584 return !m_workerGlobalScope->thread()->runLoop().terminated();
567 } 585 }
568 586
569 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() 587 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer()
570 { 588 {
571 ASSERT(!hasTerminatedPeer()); 589 ASSERT(!hasTerminatedPeer());
590
591 // It is important to seprate the task creation from the
592 // waitForMethodCompletion call. See the above comment.
593 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::dest roy, m_peer));
572 #if ENABLE(OILPAN) 594 #if ENABLE(OILPAN)
573 // The worker thread has to wait for the main thread to complete Peer::destr oy, 595 // 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 596 // 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 597 // references to on-heap objects allocated in the thread heap of the worker thread
576 // before the worker thread shuts down. 598 // before the worker thread shuts down.
577 waitForMethodCompletion(CallClosureTask::create(bind(&Peer::destroy, m_peer) )); 599 waitForMethodCompletion(task.release());
578 #else 600 #else
579 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); 601 m_loaderProxy.postTaskToLoader(task.release());
580 #endif 602 #endif
581 603
582 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. 604 // Peer::destroy() deletes m_peer and then m_syncHelper will be released.
583 // We must not touch m_syncHelper any more. 605 // We must not touch m_syncHelper any more.
584 m_syncHelper = nullptr; 606 m_syncHelper = nullptr;
585 607
586 // We won't use this any more. 608 // We won't use this any more.
587 m_workerGlobalScope = nullptr; 609 m_workerGlobalScope = nullptr;
588 } 610 }
589 611
590 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor) 612 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor)
591 { 613 {
592 visitor->trace(m_workerClientWrapper); 614 visitor->trace(m_workerClientWrapper);
593 visitor->trace(m_workerGlobalScope); 615 visitor->trace(m_workerGlobalScope);
594 visitor->trace(m_syncHelper); 616 visitor->trace(m_syncHelper);
595 visitor->trace(m_peer); 617 visitor->trace(m_peer);
596 } 618 }
597 619
598 } // namespace WebCore 620 } // 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