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

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp

Issue 2913303002: Avoid unsafe heap access from audio thread. (Closed)
Patch Set: Created 3 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 active_source_nodes_.erase(i); 673 active_source_nodes_.erase(i);
674 } 674 }
675 finished_source_nodes_.clear(); 675 finished_source_nodes_.clear();
676 } 676 }
677 677
678 bool BaseAudioContext::ReleaseFinishedSourceNodes() { 678 bool BaseAudioContext::ReleaseFinishedSourceNodes() {
679 DCHECK(IsGraphOwner()); 679 DCHECK(IsGraphOwner());
680 DCHECK(IsAudioThread()); 680 DCHECK(IsAudioThread());
681 bool did_remove = false; 681 bool did_remove = false;
682 for (AudioHandler* handler : finished_source_handlers_) { 682 for (AudioHandler* handler : finished_source_handlers_) {
683 // See HandleStoppableSourceNodes() comment for why
684 // this is needed.
685 ThreadState::GCLockScope gc_lock(ThreadState::MainThreadState());
hongchan 2017/06/01 16:08:55 rtoy@ If we have this lock, perhaps we don't need
Raymond Toy 2017/06/01 18:20:47 Based on the name of the class, I think we still n
sof 2017/06/01 21:10:05 That's correct, it prevents the audio thread from
haraken 2017/06/02 02:42:25 I'm a bit confused. Is it possible that a GC runs
sof 2017/06/02 05:39:40 Yes, that can happen - the lock is over an off-hea
686
683 for (AudioNode* node : active_source_nodes_) { 687 for (AudioNode* node : active_source_nodes_) {
684 if (finished_source_nodes_.Contains(node)) 688 if (finished_source_nodes_.Contains(node))
685 continue; 689 continue;
686 if (handler == &node->Handler()) { 690 if (handler == &node->Handler()) {
687 handler->BreakConnection(); 691 handler->BreakConnection();
688 finished_source_nodes_.insert(node); 692 finished_source_nodes_.insert(node);
689 did_remove = true; 693 did_remove = true;
690 break; 694 break;
691 } 695 }
692 } 696 }
(...skipping 12 matching lines...) Expand all
705 709
706 void BaseAudioContext::ReleaseActiveSourceNodes() { 710 void BaseAudioContext::ReleaseActiveSourceNodes() {
707 DCHECK(IsMainThread()); 711 DCHECK(IsMainThread());
708 for (auto& source_node : active_source_nodes_) 712 for (auto& source_node : active_source_nodes_)
709 source_node->Handler().BreakConnection(); 713 source_node->Handler().BreakConnection();
710 714
711 active_source_nodes_.clear(); 715 active_source_nodes_.clear();
712 } 716 }
713 717
714 void BaseAudioContext::HandleStoppableSourceNodes() { 718 void BaseAudioContext::HandleStoppableSourceNodes() {
719 DCHECK(IsAudioThread());
715 DCHECK(IsGraphOwner()); 720 DCHECK(IsGraphOwner());
716 721
722 // A main thread GC must not be running while the audio
723 // thread iterates over the |active_source_nodes_| heap object.
724 ThreadState::GCLockScope gc_lock(ThreadState::MainThreadState());
Raymond Toy 2017/06/01 18:20:47 Is it possible to make this a trylock where we can
sof 2017/06/01 21:10:05 I see, thanks - a tryLock() operation could be pro
725
717 // Find AudioBufferSourceNodes to see if we can stop playing them. 726 // Find AudioBufferSourceNodes to see if we can stop playing them.
718 for (AudioNode* node : active_source_nodes_) { 727 for (AudioNode* node : active_source_nodes_) {
719 // If the AudioNode has been marked as finished and released by 728 // If the AudioNode has been marked as finished and released by
720 // the audio thread, but not yet removed by the main thread 729 // the audio thread, but not yet removed by the main thread
721 // (see releaseActiveSourceNodes() above), |node| must not be 730 // (see releaseActiveSourceNodes() above), |node| must not be
722 // touched as its handler may have been released already. 731 // touched as its handler may have been released already.
723 if (finished_source_nodes_.Contains(node)) 732 if (finished_source_nodes_.Contains(node))
724 continue; 733 continue;
725 if (node->Handler().GetNodeType() == 734 if (node->Handler().GetNodeType() ==
726 AudioHandler::kNodeTypeAudioBufferSource) { 735 AudioHandler::kNodeTypeAudioBufferSource) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 } 930 }
922 931
923 SecurityOrigin* BaseAudioContext::GetSecurityOrigin() const { 932 SecurityOrigin* BaseAudioContext::GetSecurityOrigin() const {
924 if (GetExecutionContext()) 933 if (GetExecutionContext())
925 return GetExecutionContext()->GetSecurityOrigin(); 934 return GetExecutionContext()->GetSecurityOrigin();
926 935
927 return nullptr; 936 return nullptr;
928 } 937 }
929 938
930 } // namespace blink 939 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698