Delete Channels without ChannelManager lock.
Triggered Helgrind error, as deleting a Channel will also unregister a module which has called GetChannel(), resulting in a cyclic lock graph. This change will also allow other threads to access the ChannelManager instance while Channels are deleted. R=xians@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1946005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4505 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
bd21fb5f8d
commit
58d76cb635
@ -78,22 +78,34 @@ void ChannelManager::GetAllChannels(std::vector<ChannelOwner>* channels) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ChannelManager::DestroyChannel(int32_t channel_id) {
|
void ChannelManager::DestroyChannel(int32_t channel_id) {
|
||||||
CriticalSectionScoped crit(lock_.get());
|
|
||||||
assert(channel_id >= 0);
|
assert(channel_id >= 0);
|
||||||
|
// Holds a reference to a channel, this is used so that we never delete
|
||||||
|
// Channels while holding a lock, but rather when the method returns.
|
||||||
|
ChannelOwner reference(NULL);
|
||||||
|
{
|
||||||
|
CriticalSectionScoped crit(lock_.get());
|
||||||
|
|
||||||
for (std::vector<ChannelOwner>::iterator it = channels_.begin();
|
for (std::vector<ChannelOwner>::iterator it = channels_.begin();
|
||||||
it != channels_.end();
|
it != channels_.end();
|
||||||
++it) {
|
++it) {
|
||||||
if (it->channel()->ChannelId() == channel_id) {
|
if (it->channel()->ChannelId() == channel_id) {
|
||||||
channels_.erase(it);
|
reference = *it;
|
||||||
break;
|
channels_.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelManager::DestroyAllChannels() {
|
void ChannelManager::DestroyAllChannels() {
|
||||||
CriticalSectionScoped crit(lock_.get());
|
// Holds references so that Channels are not destroyed while holding this
|
||||||
channels_.clear();
|
// lock, but rather when the method returns.
|
||||||
|
std::vector<ChannelOwner> references;
|
||||||
|
{
|
||||||
|
CriticalSectionScoped crit(lock_.get());
|
||||||
|
references = channels_;
|
||||||
|
channels_.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ChannelManager::NumOfChannels() const {
|
size_t ChannelManager::NumOfChannels() const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user