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/webrtc@4505 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/voice_engine/channel_manager.cc b/voice_engine/channel_manager.cc
index 6cf935d..8110bb6 100644
--- a/voice_engine/channel_manager.cc
+++ b/voice_engine/channel_manager.cc
@@ -78,22 +78,34 @@
 }
 
 void ChannelManager::DestroyChannel(int32_t channel_id) {
-  CriticalSectionScoped crit(lock_.get());
   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();
-       it != channels_.end();
-       ++it) {
-    if (it->channel()->ChannelId() == channel_id) {
-      channels_.erase(it);
-      break;
+    for (std::vector<ChannelOwner>::iterator it = channels_.begin();
+         it != channels_.end();
+         ++it) {
+      if (it->channel()->ChannelId() == channel_id) {
+        reference = *it;
+        channels_.erase(it);
+        break;
+      }
     }
   }
 }
 
 void ChannelManager::DestroyAllChannels() {
-  CriticalSectionScoped crit(lock_.get());
-  channels_.clear();
+  // Holds references so that Channels are not destroyed while holding this
+  // lock, but rather when the method returns.
+  std::vector<ChannelOwner> references;
+  {
+    CriticalSectionScoped crit(lock_.get());
+    references = channels_;
+    channels_.clear();
+  }
 }
 
 size_t ChannelManager::NumOfChannels() const {