OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |