1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/common.h" 12 #include "webrtc/voice_engine/channel_manager.h" 13 14 #include "webrtc/voice_engine/channel.h" 15 16 namespace webrtc { 17 namespace voe { 18 19 ChannelOwner::ChannelOwner(class Channel* channel) 20 : channel_ref_(new ChannelRef(channel)) {} 21 22 ChannelOwner::ChannelOwner(const ChannelOwner& channel_owner) 23 : channel_ref_(channel_owner.channel_ref_) { 24 ++channel_ref_->ref_count; 25 } 26 27 ChannelOwner::~ChannelOwner() { 28 if (--channel_ref_->ref_count == 0) 29 delete channel_ref_; 30 } 31 32 ChannelOwner& ChannelOwner::operator=(const ChannelOwner& other) { 33 if (other.channel_ref_ == channel_ref_) 34 return *this; 35 36 if (--channel_ref_->ref_count == 0) 37 delete channel_ref_; 38 39 channel_ref_ = other.channel_ref_; 40 ++channel_ref_->ref_count; 41 42 return *this; 43 } 44 45 ChannelOwner::ChannelRef::ChannelRef(class Channel* channel) 46 : channel(channel), ref_count(1) {} 47 48 ChannelManager::ChannelManager(uint32_t instance_id, const Config& config) 49 : instance_id_(instance_id), 50 last_channel_id_(-1), 51 lock_(CriticalSectionWrapper::CreateCriticalSection()), 52 config_(config) {} 53 54 ChannelOwner ChannelManager::CreateChannel() { 55 return CreateChannelInternal(config_); 56 } 57 58 ChannelOwner ChannelManager::CreateChannel(const Config& external_config) { 59 return CreateChannelInternal(external_config); 60 } 61 62 ChannelOwner ChannelManager::CreateChannelInternal(const Config& config) { 63 Channel* channel; 64 Channel::CreateChannel(channel, ++last_channel_id_, instance_id_, config); 65 ChannelOwner channel_owner(channel); 66 67 CriticalSectionScoped crit(lock_.get()); 68 69 channels_.push_back(channel_owner); 70 71 return channel_owner; 72 } 73 74 ChannelOwner ChannelManager::GetChannel(int32_t channel_id) { 75 CriticalSectionScoped crit(lock_.get()); 76 77 for (size_t i = 0; i < channels_.size(); ++i) { 78 if (channels_[i].channel()->ChannelId() == channel_id) 79 return channels_[i]; 80 } 81 return ChannelOwner(NULL); 82 } 83 84 void ChannelManager::GetAllChannels(std::vector<ChannelOwner>* channels) { 85 CriticalSectionScoped crit(lock_.get()); 86 87 *channels = channels_; 88 } 89 90 void ChannelManager::DestroyChannel(int32_t channel_id) { 91 assert(channel_id >= 0); 92 // Holds a reference to a channel, this is used so that we never delete 93 // Channels while holding a lock, but rather when the method returns. 94 ChannelOwner reference(NULL); 95 { 96 CriticalSectionScoped crit(lock_.get()); 97 98 for (std::vector<ChannelOwner>::iterator it = channels_.begin(); 99 it != channels_.end(); 100 ++it) { 101 if (it->channel()->ChannelId() == channel_id) { 102 reference = *it; 103 channels_.erase(it); 104 break; 105 } 106 } 107 } 108 } 109 110 void ChannelManager::DestroyAllChannels() { 111 // Holds references so that Channels are not destroyed while holding this 112 // lock, but rather when the method returns. 113 std::vector<ChannelOwner> references; 114 { 115 CriticalSectionScoped crit(lock_.get()); 116 references = channels_; 117 channels_.clear(); 118 } 119 } 120 121 size_t ChannelManager::NumOfChannels() const { 122 CriticalSectionScoped crit(lock_.get()); 123 return channels_.size(); 124 } 125 126 ChannelManager::Iterator::Iterator(ChannelManager* channel_manager) 127 : iterator_pos_(0) { 128 channel_manager->GetAllChannels(&channels_); 129 } 130 131 Channel* ChannelManager::Iterator::GetChannel() { 132 if (iterator_pos_ < channels_.size()) 133 return channels_[iterator_pos_].channel(); 134 return NULL; 135 } 136 137 bool ChannelManager::Iterator::IsValid() { 138 return iterator_pos_ < channels_.size(); 139 } 140 141 void ChannelManager::Iterator::Increment() { 142 ++iterator_pos_; 143 } 144 145 } // namespace voe 146 } // namespace webrtc 147